0

我无法决定如何解决以下情况:我有一个users具有基本属性的表,如idusernameemail等,我想记录用户选择的类别。在阅读了关于 SO 的类似问题和广泛的谷歌搜索之后,我想出了几个选项:

a)创建user_categories包含以下字段的表:

+----+---------+-------+-------+-------+
| id | user_id | sport | music | books |
+----+---------+-------+-------+-------+
|  1 |     123 |     0 |     1 |     1 |
|  2 |     543 |     1 |     0 |     0 |
|  3 |     645 |     1 |     1 |     0 |
+----+---------+-------+-------+-------+

在我的例子中,“类别”(运动、音乐、书籍)只是一个布尔类型——是/否(1/0),它表示用户是否选择了这个类别。此外,这些“类别”中不会超过 20 个(现在在我的设计中我有 12 个 - 它们都不会被删除,只是有可能会添加一些新的(更细粒度的))。

b)创建categories例如如下所示的表:

+----+----------+
| id | category |
+----+----------+
|  1 | sport    |
|  2 | music    |
|  3 | books    |
+----+----------+

然后user_categories表格看起来像这样:

+----+---------+-------------+----------------+
| id | user_id | category_id | category_value |
+----+---------+-------------+----------------+
|  1 |     123 |           1 |              0 |
|  2 |     123 |           2 |              1 |
|  3 |     123 |           3 |              1 |
+----+---------+-------------+----------------+

你能告诉我你会用这两个中的哪一个吗?(或者如果我完全错了,你能提出更好的解决方案吗?)

4

3 回答 3

1

我个人更喜欢第二种方法,它足够通用,可以在插入和查询方面实际添加应用层变化为零的类别。第一种方法需要模式更改,这是最昂贵的,并且需要传播到所有层。

我们在我们的一个企业项目中采用了类似的方法,向业务对象添加属性。这种情况有点复杂,属性的数据类型不相同,所以我们为每种数据类型添加了一列(attr_id、bit_attr_value、int_attr_value ...)。这为在运行时通过管理 UI 定义属性提供了极大的灵活性,应用层代码更改为零。

于 2012-09-08T14:14:41.410 回答
1

两种方式都是可能的并且OK。

一般来说,如果您知道您永远不需要在“运动”、“音乐”、“书籍”旁边添加额外的类别,那么您可以简单地使用 1 表解决方案。

如果您认为类别(因此字段)的数量会增加 - 然后选择第二个。添加记录总是比字段更容易。您永远不需要更改表的结构。

在您的情况下,当您知道将来可能会添加一些字段时,您最好选择第二种方式。

于 2012-09-08T14:16:22.483 回答
1

a)在以下情况下可能是可行的:

  • 您绝对必须避免加入(出于性能原因)
  • 并且类别是静态的,因此您不必不断地添加新列user_categories(这很昂贵,并且取决于 DBMS 可能需要对整个表进行排他锁,从而有效地使其在更改期间不可用)。

我会修改b)的原始设计并删除category_value. 因此,如果相应的行存在,则用户在类别中,如果user_categories不存在,则用户不在类别中。这允许:

  • 轻松添加新类别
  • 如果大多数用户属于所有类别中的少数,实际上可以节省空间(并因此缓存性能),
  • 可能需要更多的 JOINing(然后可能不需要 - 取决于您实际需要查询的内容)。

我怀疑b)会更适合您的需求。

于 2012-09-08T22:01:42.730 回答