Nano Hash - криптовалюты, майнинг, программирование

PHP - таблица базы данных поиска MySQL возвращает результат с процентным соответствием

На моем сайте я позволяю пользователям выбирать то, что им нравится или что им интересно. Это делается с помощью предварительно определенного выпадающего меню, поэтому каждый раз, когда пользователь входит на сайт, он получает список пользователей, которые имеют те же интересы, что и их.

Это делается путем подбора интересов вошедшего в систему пользователя (хранение в БД) и сопоставления с другим пользователем на сайте с использованием предложения MySQL WHERE. Но у меня возникли проблемы с тем, как показать процент или оценку рядом с каждым пользователем, чтобы показать, насколько близко они соответствуют заинтересованности зарегистрированного пользователя.

Например:

  • user1 -- 60% соответствуют вашим интересам
  • user1 -- 30% соответствуют вашим интересам
  • user2 -- 20% соответствуют вашим интересам

У каждого пользователя есть 5 разных интересов, если все совпадают, чем на 100%.

Пример структуры таблицы:

CREATE TABLE IF NOT EXISTS `helloworld` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `like1` varchar(300) NOT NULL,
  `like2` varchar(300) NOT NULL,
  `like3` varchar(300) NOT NULL,
  `name` varchar(300) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

пример запроса:

SELECT * FROM helloworld WHERE like1='football' AND like2='art'

Я думал использовать функцию COUNT, но я не уверен? или я должен использовать подзапросы?

РЕДАКТИРОВАТЬ: я использую PHP для языка на стороне сервера. пользователь НЕ может печатать свои собственные лайки, должен использовать предварительно определенный список.


  • Если бы у меня были like1='art' и like2='football', соответствовал бы я приведенному выше примеру запроса? 29.10.2011
  • извините, нет, вы не совпадете, так как искусство всегда находится в столбце like2, а не like1. Пользователям не разрешается вводить или смешивать и сопоставлять свои лайки, они должны выбирать из заранее определенного списка (выпадающее меню). Сайт реализован с использованием php и mysql, если это поможет. 30.10.2011

Ответы:


1

Вот как я это делаю. Предположим, что $like1, $like2 и $like3 — это значения вашего текущего пользователя:

SELECT (IF(like1='$like1',1,0) + IF(like2='$like2',1,0) + IF(like3='$like3',1,0))/3*100 match_percent,
COUNT(id)
FROM helloworld
GROUP BY match_percent;
29.10.2011
  • вы (неправильно) предположили, что лайки будут храниться в одном и том же столбце, что ограничило бы общее количество разных лайков в базе данных до 5. неправильно! 30.10.2011
  • Я должен был спросить плакат, но предположение не обязательно неверно. Итак, все ли варианты доступны для каждого столбца или каждый лайк имеет отдельный набор вариантов? Если каждый из них отличается, мой код в порядке, в противном случае вам понадобится более нормализованное решение. 30.10.2011
  • правильно, все значения различны для каждого столбца. проверил ваш код, похоже, он дает результаты, которые я ищу. но всегда возвращает одного пользователя с 0% по какой-то причине.. 30.10.2011
  • Я бы предположил, что 5 столбцов представляют собой набор лайков, возможно, в порядке приоритета, возможно, нет, но любой подобный столбец может иметь любое подобное значение, и все подобные столбцы имеют разные (или нулевые) значения в любой данной строке. 30.10.2011
  • @davidethell после дальнейшего тестирования я заметил, что ваш запрос вернет только одного пользователя, если будет выполнено 100% совпадение, даже если у них может быть несколько других пользователей, которые могут иметь такой же интерес, как и вы, и совпадают на 100%. 01.11.2011

  • 2

    У вас есть отношение «многие к человеку» между пользователем и лайками. Ваша таблица нарушает 1NF — у вас есть «повторяющаяся группа» столбцов like. Вместо этого создайте для этого отдельную таблицу ассоциаций:

    create table user_likes (
        user_id int(9) NOT NULL,
        like_name varchar(300) NOT NULL
    );
    

    Теперь вы можете использовать более простые запросы, чтобы получить количество совпадений — я оставлю это вам, чтобы решить :)

    Подсказка: вы можете использовать битовую маску, чтобы помочь определить совпадения, назначая предопределенную степень числа 2 для каждого отдельного like_name (справка — это таблица like_names).

    29.10.2011

    3

    Вам лучше проверить это на уровне PHP. Учитывая интересы каждого пользователя, вы можете получить оценку, используя count() по результату array_intersect(), чтобы сравнить интересы посетителя и других пользователей (http://www.php.net/manual/en/function.array-intersect. php). Если вы разрешите 5 интересов, это будет (5 * count(array_intersect({params})))%. За отсутствие совпадения 0%, за 4 совпадения 80%.

    29.10.2011

    4

    Во-первых, я думаю, вам нужна другая схема. Тот, который у вас есть, сильно усложнит вашу задачу, потому что он недостаточно гибкий. Я рекомендую что-то вроде этого:

    CREATE TABLE `users` (
        `id`        INT NOT NULL AUTO_INCREMENT,
        `name`      VARCHAR(300) NOT NULL,
        PRIMARY KEY (`id`)
    );
    
    CREATE TABLE `likes` (
        `user`      INT NOT NULL,
        `interest`  VARCHAR NOT NULL,
        PRIMARY KEY (`user`,`interest`)
    );
    

    (Извините, я не помню, как настроить связь FK в MySQL, но я уверен, что вы легко это поймете.)

    Затем, чтобы определить количество лайков для каждого пользователя:

    SELECT COUNT(*)
    FROM users
    JOIN likes ON likes.user=users.id
    WHERE users.name = 'bob';
    

    Затем, чтобы определить, сколько лайков есть у двух пользователей:

    SELECT COUNT(*)
    FROM users AS u1
    JOIN likes AS l1 ON (l1.user = u1.id)
    JOIN likes AS l2 ON (l1.interest = l2.interest)
    JOIN users AS u2 ON (l2.user = u2.id)
    WHERE u1.name = 'bob'
        AND u2.name = 'alice';
    

    Затем, основываясь на этих трех числах, вы можете рассчитать свои проценты по своему усмотрению - возможно, в своем клиентском коде, но вы можете использовать подзапросы, чтобы сделать все это на стороне SQL, если хотите.

    Пример:

    USERS:
     id | name
    ----+-------
      1 | bob
      2 | alice
    
    LIKES:
     user | interest
    ------+----------
        1 | fish
        1 | baseball
        2 | fish
        2 | cooking
        2 | baseball
    

    Выполнение первого запроса для bob и alice покажет, что у Боба 2 интереса, а у Алисы 3 интереса. Затем выполнение второго запроса покажет, что у Боба и Алисы есть 2 общие интересы.

    Затем вы можете показать Бобу, что Алиса разделяет 100 % его интересов (2/2 = 100 %), и вы можете показать Алисе, что Боб разделяет 66 % (2/3 = 66 %) ее интересов.

    29.10.2011

    5

    Это сделает это с вашей текущей схемой:

    select
        t2.id,
        t2.name
        sum(
            t1.like1 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
            t1.like2 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
            t1.like3 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
            t1.like4 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) +
            t1.like5 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5)
        ) * 20 as percent_match
    from helloworld t1
    left join helloworld t2 on t1.id != t2.id
    group by 1, 2
    order by 3 desc;
    

    Это работает, потому что true в mysql равно 1 - суммирование истин даст общее количество совпадений.

    31.10.2011
  • какова цель использования * 20? и что-нибудь из t1.like2 в (t2.like1, t2.like2. t2.like3. t2.like4. t2.like5) - вторая строка, похоже, не работает. Как вы думаете, следует ли суммировать каждое из вышеперечисленных по отдельности? 01.11.2011
  • @TheDeveloper * 20 используется для преобразования в проценты. SUM() даст числа между 0 и 5, но вам нужны проценты между 0 и 100... отсюда и * 20. Также у меня были точки вместо запятых (т.е. синтаксическая ошибка) - попробуйте сейчас. 01.11.2011
  • синтаксическая ошибка все еще выходит, я не мог ее решить. Ошибка была в том, что проверьте руководство, соответствующее версии вашего сервера MySQL, на предмет правильного синтаксиса для использования рядом с 'sum( t1.like1 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 'at строка 4 03.11.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..