可能重复:
How to Store Multiple Options selected by User in a Table
我对此非常困惑。
我希望我的用户能够限制可以联系他们的人。因此,我需要为每个用户及其选定的条件创建一个新的RESTRICTIONS表,该表将包含每个用户限制条件的列。这些专栏将包括年龄,收入,寻找,药物等。其中一些专栏(寻找,药物等)可能包含多个选择,其中存在我的问题。如何以这种方式构造表,考虑到某些条件(列)可以有多个值而其他条件没有?
我被告知有关连接表和枚举值(我之前从未使用过的这两个值),但我真的很困惑,我将如何构建一个表,其中一些列(不是全部),可以包含多个选择。
如何在表格的特定列中存储这些多个选项,以及如何构建RESTRICTIONS的整个表格?
答案 0 :(得分:2)
DB列(至少在理论上)应该 NOT 保存多个值。不幸的是,有些程序员在一个列中存储多个值(例如用逗号分隔的值) - 那些程序员(在大多数情况下)破坏了DB和SQL的概念。
我建议您阅读 Database Normalization ,以便开始组织您的表格。并且,尽力实现 Codd's Third Normal Form
答案 1 :(得分:1)
您可能需要多个表格。
你已经拥有了“用户”表,对吗?如果您的某个“限制”条件每个用户只能有一个值,则该列属于“users”表。因此,您可能在users表中有“min_age”和“max_age”列,因为可能每个用户只有一个连续的年龄范围,他们正在寻找。
另一方面,对于可以具有多个值的每个限制条件,您需要一个新表。所以你可能有一个表“users_restrictions_drugs”,主键是(user,drug)。但是您可能还有一个表“users_restrictions_lookingfor”,其中主键是(user,lookingfor)。无论“寻找”是什么。
对于其中一些表,它可能有意义
答案 2 :(得分:1)
这是最简单的方法。多个属性成为第二个表中的行。
CREATE TABLE restrictions (
user_id INTEGER PRIMARY KEY, -- references users (user_id), not shown
age_restriction VARCHAR(10) NULL,
income_restriction VARCHAR(20) NULL
);
CREATE TABLE looking_for (
user_id INTEGER NOT NULL REFERENCES restrictions (user_id),
looking_for VARCHAR(35) NOT NULL, -- could also be a foreign key.
PRIMARY KEY (user_id, looking_for)
);
INSERT INTO restrictions (user_id) VALUES (1);
INSERT INTO restrictions (user_id, age_restriction) VALUES (2, '> 25');
INSERT INTO looking_for VALUES (1, 'boat');
INSERT INTO looking_for VALUES (1, 'dunky fazoo');
如果您想接受多个年龄限制,例如'> 25'和'< 55',你也可以为此建立另一张桌子。
要检索所有限制,请使用OUTER JOIN。
SELECT r.user_id, r.age_restriction, r.income_restriction, lf.looking_for
FROM restrictions r
LEFT JOIN looking_for lf ON lf.user_id = r.user_id
答案 3 :(得分:1)
table restrictions
user_id smoker_ok min_height max_height min_age max_age
-------------------------------------------------------
1 Y 150 200 24 34
2 N 100 180 32 57
table drug_restrictions
user_id drug_id drug_allowed
----------------------------------
1 H N
1 M Y
2 E Y
将是一个例子。在限制表中,您可以存储显式的,奇异的值 - 吸烟者是或否,或最小和最大要求。 对于有多个选择的每个表,您可以创建一个连接表 - 我给出了一个药物示例。 在drug_restrictions表中,用户1表示她不希望人们使用H,但确实希望人们使用M.
此解决方案允许您使用“drug_id”作为数据库中任何表的外键,填充用户界面上的“药物”字段。它允许您对这些外键使用常规的标准SQL约定,并通过将它们声明为外键在数据库级别强制执行它们。
当然,缺点是你必须查询大量的表来查找匹配的记录,这并不是很有趣。
因此,您也可以遵循Catcall的建议 - 这会大大减少表的数量,但却无法使用“标准”外键完整性约束。这可能没问题 - 它肯定会更快。
我不愿意使用枚举 - 它们往往导致复杂的查询,而不是“标准”SQL。
答案 4 :(得分:0)
如果某些列具有重复值,则表没有问题。考虑用户的tbale;如果两个用户有相同的生日,那没问题吗?
唯一的问题是主键多次出现的表。例如,用户表可能会将username
作为其主键,并且您不希望两个用户具有相同的用户名。
因此,制作一个列出用户的表,一个列出限制的表,以及一个连接两者的表。后者将为每个用户/权限组合提供一个条目。