處理這個問題的基本方法是使用多對多連接表。每個用戶可以有很多愛好。每個愛好都可以有很多用戶。這是基本的東西,你可以找到任何地方的信息,並@juergend already covered that。
更難的部分是跟蹤關於各種愛好和興趣的不同信息。就像他們的愛好是「棒球」一樣,你可能想跟蹤他們的位置,但如果他們的愛好是「旅行」,你可能想跟蹤他們最喜歡的國家。用典型的SQL關係做這件事會導致表和列的快速擴散。
混合方法是使用新的JSON data type來存儲一些非結構化數據。要擴展@ juergend的例子,你可以在Person_Interests中添加一個字段,這個字段可以存儲一些關於這個人的興趣的細節。
create table Person_Interests (
InterestID integer references Interests(ID),
PersonID integer references Persons(ID),
Details JSON
);
現在你可以補充說,45號人有興趣12(旅行),他們最喜歡的國家是吉布提,他們去過45個國家。
insert into person_interests
(InterestID, PersonID, Details)
(12, 45, '{"favorite_country": "Djibouti", "countries_visited": 45}');
你也可以使用JSON的搜索功能找到,例如,每個人她最喜歡的國家是吉布提。
select p.id, p.name
from person_interests pi
join persons p on p.id = pi.personid
where pi.details->"$.favorite_country" = "Djibouti"
這裏的優點是靈活性:興趣及其屬性不受數據庫架構的限制。
缺點是性能。 JSON數據類型不是最有效的,並且indexing a JSON column in MySQL is complicated。良好的索引對於良好的SQL性能至關重要。因此,當您找出常見模式時,您可能希望將常用屬性轉換爲真實表格中的實際列。
另一種選擇是使用table inheritance。這是Postgres的一個特性,而不是MySQL,我建議考慮切換。 Postgres也有better and more mature JSON support和JSON columns are easier to index。
使用表繼承,而不必爲每個不同的興趣編寫一個全新的表,您可以製作從更通用的表繼承的特定表。
create table person_interests_travel (
FavoriteCountry text,
CountriesVisited text[]
) inherits(person_interests);
這仍然有InterestID,是PersonID,和詳細信息,但它增加了一些特定的列來跟蹤自己喜歡的國家,他們訪問過的國家。
請注意,text[]
。 Postgresql also supports arrays因此您可以存儲實際列表而無需創建另一個連接表。你也可以在MySQL中使用JSON字段來做到這一點,但是數組提供JSON不支持的類型約束。
你跟蹤這些愛好多少細節? – Schwern
選項2聽起來非常可怕,選項3聽起來不好並且不規範。第一種選擇是IMO的方式,您可以查看下面的@Juergen答案以獲取更多信息。 –
謝謝大家的快速回復。 @Schewrn我需要大約50個愛好和興趣(只是名字)。 –