Pergunta

Atualmente estou construindo um sistema (php e mysql), que no perfil do usuário permite que você adicione "artistas de música favoritos" a uma lista. Estiveram tentando descobrir uma maneira de comparar o usuário gosta de outros usuários e retornar uma 'amigos recomendados'.

Por exemplo:

User A Likes
- 1
- 2
- 3
- 4

User B Likes
- 1 <- A likes
- 5
- 6
- 7

User C Likes
- 1 <- A likes
- 2 <- A likes
- 8
- 9

Em seguida, com este usuário teria a seguinte recomendação:

User C
User B

Meu palpite é que, para ser capaz de fazer isso necessidade I de fazer um banco de dados relacional e padronizar a maior parte da entrada do usuário.

Então, minhas perguntas são: Qual a estrutura de banco de dados é o melhor para este tipo de comparações? Que tipo de consulta que eu deveria usar? (Não precisa ser exato)

Foi útil?

Solução

Não diretamente uma resposta à sua pergunta, mas você pode querer verificar o livro Programação Collective Intelligence . Baseado em sua pergunta que eu acho que você iria encontrá-lo muito útil.

Outras dicas

Uma implementação simples pode ter esta aparência

CREATE TABLE user_tbl(
    user_id BIGINT,
    ...
)

CREATE TABLE music_tbl(
    music_id BIGINT,
    ...
)

CREATE TABLE likes_tbl(
    user_id BIGINT,
    music_id BIGINT
)

Para encontrar todos os usuários que têm sabor semelhante a um determinado utilizador que faça o seguinte:

select u1.user_id, u2.user_id, count(*) as weight from likes_tbl u1, likes_tbl u2
where u1.music_id = u2.music_id and u1.user_id <> u2.user_id and u1.user_id = @user_id
group by u1.user_id, u2.user_id

A coluna de peso é o número de artistas que os usuários têm na coluna, por isso quanto maior o peso, mais eles têm em comum. Então você pode recomendar o top 5 usuários com o peso heighest.

Isso pode ser estendido de maneiras diferentes. Uma possibilidade é adicionar um genre_id ao music_tbl e likes_tbl e, em seguida, fazer a junção em genre_id.

Para não repetir o que já foi publicado, mas ...

--
-- Working MySQL implementation of a "user compatibility" schema.
--


DROP TABLE IF EXISTS favourite;
DROP TABLE IF EXISTS artist;
DROP TABLE IF EXISTS users;


CREATE TABLE users (
 user_id INT NOT NULL AUTO_INCREMENT,
 name VARCHAR(32),
 PRIMARY KEY (user_id)
);


CREATE TABLE artist (
 artist_id INT NOT NULL AUTO_INCREMENT,
 name VARCHAR(32),
 PRIMARY KEY (artist_id)
);


CREATE TABLE favourite (
 favourite_id INT NOT NULL AUTO_INCREMENT,
 user_id INT NOT NULL,
 artist_id INT NOT NULL,
 UNIQUE (user_id, artist_id),
 PRIMARY KEY (favourite_id),
 FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE,
 FOREIGN KEY (artist_id) REFERENCES artist (artist_id) ON DELETE CASCADE
);


INSERT INTO users
 (name)
VALUES
 ("Alice"),
 ("Bob"),
 ("Carol"),
 ("Dave")
;


INSERT INTO artist
 (name)
VALUES
 ("Jewel"),
 ("Sarah McLachlan"),
 ("Britney Spears"),
 ("David Bowie"),
 ("The Doors")
;


INSERT INTO favourite
 (user_id, artist_id)
VALUES
 (
  (SELECT user_id FROM users WHERE name = "Alice"),
  (SELECT artist_id FROM artist WHERE name = "Jewel")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Alice"),
  (SELECT artist_id FROM artist WHERE name = "Sarah McLachlan")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Bob"),
  (SELECT artist_id FROM artist WHERE name = "Jewel")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Bob"),
  (SELECT artist_id FROM artist WHERE name = "Sarah McLachlan")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Bob"),
  (SELECT artist_id FROM artist WHERE name = "Britney Spears")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Bob"),
  (SELECT artist_id FROM artist WHERE name = "David Bowie")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Carol"),
  (SELECT artist_id FROM artist WHERE name = "David Bowie")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Carol"),
  (SELECT artist_id FROM artist WHERE name = "The Doors")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Dave"),
  (SELECT artist_id FROM artist WHERE name = "Jewel")
 ),
 (
  (SELECT user_id FROM users WHERE name = "Dave"),
  (SELECT artist_id FROM artist WHERE name = "The Doors")
 )
;


SELECT
 t0.user_id myuser,
 t1.user_id friend,
 COUNT(*)
FROM favourite t0
JOIN favourite t1 ON t1.artist_id = t0.artist_id
WHERE t0.user_id != t1.user_id
GROUP BY t0.user_id, t1.user_id;


--
-- The same thing, but returning names!
--

SELECT
 t0u.name myuser,
 t1u.name friend,
 COUNT(*)
FROM favourite t0
JOIN favourite t1 ON t1.artist_id = t0.artist_id
JOIN users t0u ON t0u.user_id = t0.user_id
JOIN users t1u ON t1u.user_id = t1.user_id
WHERE t0.user_id != t1.user_id
GROUP BY t0.user_id, t1.user_id;

Boa sorte!

Se você tiver uma mesa de Artistas e uma tabela de usuários, você pode ter um FavoriteArtists mesa com duas chaves estrangeiras:. O usuário, eo artista Favorito

Em seguida, basta obter outros usuários que têm favoritos semelhantes e recomendar amigos para o usuário com base em alguma sobreposição limiar.

Tabelas

User
userid int
FirstName varchar(30)
LastName varchar(30)

Song
songid int
Title varchar(30)
Artist varchar(30)

UserSong
userid
songid

Consulta

select User.userid, User.FirstName, User.LastName
from UserSong
inner join Song
on UserSong.songid=Song.songid
inner join User
on UserSong.userid=User.userid
where Song.Artist='Some Artist'

Menos detalhado Consulta Usando um Natural Junte-se

select User.userid, User.FirstName, User.LastName
from UserSong
natural join Song
natural join User
where Song.Artist='Some Artist'

(Note que eu não testei este, ainda. Alguém me corrija se eu estiver errado).

A consulta acima lhe dará uma lista de todos os usuários que "como" o artista dado. Você pode então usar essa lista para mostrar aos outros quem mais gosta do que eles fazem.

No SQL Server:

CREATE TABLE Users (
UserID BIGINT IDENTITY (1,1) NOT NULL
--Other columns here
)


CREATE TABLE Artists (
ArtistID BIGINT IDENTITY(1,1) NOT NULL
-- Other columns
)


CREATE TABLE FavoriteArtists (
UserID BIGINT, ArtistID BIGINT )

consulta para selecionar os usuários com os mesmos gostos:

SELECT 
FROM   FavoriteArtists u, FavoriteArtists f
WHERE  u.ArtistID = f.ArtistID AND u.UserID = @TARGET_USER AND f.UserID <> @TARGET_USER
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top