存储可变数量偏好的最佳方法是什么?

时间:2011-04-07 20:01:03

标签: sql database database-design

我需要存储可变数量的用户首选项。例如,如果我们谈论电影,用户1喜欢电影[A,B,C],用户2喜欢[C,D]等。 什么是“正确”将这些存储在表格中的最佳方式 - 因此我可以有效地搜索这些首选项,如果有新的首选项类型等,则不会有多个表格。

5 个答案:

答案 0 :(得分:6)

将一个表格包含用户,一个表格包含电影,第三个表格(偏好设置)用于将用户映射到电影。像这样,用户可以喜欢多部电影,不同的用户可以喜欢同一部电影。它基本上是一种M:N关系。这是你在找什么?

答案 1 :(得分:3)

我建议您查看Entity-Attribute-Value model 这为逻辑模式的更改和基数提供了极大的灵活性 stackoverflow postings中讨论了各种EAV实现和细节,也许您可​​以从this one开始,因为它通常涵盖了此处提出的问题类型。

例如,当应用程序发展并需要其他类型的首选项时,根本不需要修改物理模式(支持SQL表),新的首选项将成为“属性”表中的条目。

EAV模型的主要缺点是桌面结构稍微复杂一些,效率也会下降(比如说有百万以上的实体)。
使用简单的关系模型,数据模型在数据库[物理]模式中更容易显现。效率损失主要来自于Values表一次只存储一个Attribute值(阻止组合索引的创建等),并且相对于存储相同的记录数量可能会变得相当大。数据采用简单的关系形式。

修改(关于表现)
我已经相对成功地获得了每个/最多400万行的数据实例,平均有十几个属性。我们可以得出的精确“里程数”随着数据的稀疏性和某些属性值的相对选择性而变化。有几种“交易技巧”可以提高性能,代价是进一步使实施变得复杂:

  • 在Entity表中存储最常见的共享单值属性,而不是(或除了)Values表。
  • 使用多个值表。这样的“分区”可以由数据类型,属性ID范围......
  • 驱动

答案 2 :(得分:1)

-- Predicate: User has id number :user_id.
create table users (
  user_id integer primary key
);

-- Predicate: Movie has id number :movie_id and name :movie_name.
create table movies (
  movie_id integer primary key,
  movie_name varchar(150) not null  -- Movie names aren't unique.
);

-- Predicate: User :user_id likes to watch movie :movie_id.
create table movie_preferences (
  user_id integer references users (user_id),
  movie_id integer references movies (movie_id),
  primary key (user_id, movie_id)
);

如果您以后有不同的偏好,比如餐馆,那么您需要一张餐馆桌和一张餐馆偏好表。

-- Predicate: Restaurant has id number :restaurant_id and name :restaurant_name,
-- and is known for its :known_cuisine cooking.
create table restaurants (
  restaurant_id integer primary key,
  restaurant_name varchar(150) not null,
  known_cuisine varchar(30) not null
);

-- Predicate: User :user_id likes to eat at restaurant :restaurant_id.
create table restaurant_preferences (
  user_id integer references users (user_id),
  restaurant_id integer references restaurants (restaurant_id),
  primary key (user_id, restaurant_id)
);

你需要额外的表来获得额外的偏好,因为电影与餐馆不同,而“我喜欢'Top Gun'”并不意味着“我喜欢汉堡王”。

你不会有很多桌子。每个首选项只有一个表。 (因为你必须首先实现一个餐馆餐桌才能识别它们,对吗?)

答案 3 :(得分:0)

答案 4 :(得分:0)

您是否可以创建一个包含可变数量的首选项的查找表?

创建新首选项后,会将它们放入具有相应ID的表中。

然后使用

创建一个连接表(多对多)
UserID
PreferenceID