Sql 一个查找表还是多个查找表?

Sql 一个查找表还是多个查找表?,sql,database-design,Sql,Database Design,我需要保存基本会员数据,并添加其他属性,如性别、教育程度、职业、婚姻状况、身高、居住状况等 我有大约15-18个查找表,所有表都有(id、名称、值),所有属性都有字符串值 我是否应该创建成员表tbl_members,并为上述每个属性分别创建15-18个查找表: tbl_成员: mem_Id mem_email mem_password Gender_Id education_Id profession_id marital_status_Id height_Id residency_status

我需要保存基本会员数据,并添加其他属性,如性别、教育程度、职业、婚姻状况、身高、居住状况等


我有大约15-18个查找表,所有表都有(id、名称、值),所有属性都有字符串值

我是否应该创建成员表
tbl_members
,并为上述每个属性分别创建15-18个查找表:

tbl_成员

mem_Id
mem_email
mem_password
Gender_Id
education_Id
profession_id
marital_status_Id
height_Id
residency_status_Id
att_Id
att_Value
att_Type_Id
att_type_Id
att_type_name
mem_id
att_id
或者我应该只创建一个查找表
tbl\u属性
tbl\u属性类型

待定属性

mem_Id
mem_email
mem_password
Gender_Id
education_Id
profession_id
marital_status_Id
height_Id
residency_status_Id
att_Id
att_Value
att_Type_Id
att_type_Id
att_type_name
mem_id
att_id
示例数据:

001 - Male - 001
002 - Female - 001
003 - Graduate - 002
004 - Masters - 002
005 - Engineer - 003
006 - Designer - 003
001 - Gender
002 - Education
003 - Profession
待定属性类型

mem_Id
mem_email
mem_password
Gender_Id
education_Id
profession_id
marital_status_Id
height_Id
residency_status_Id
att_Id
att_Value
att_Type_Id
att_type_Id
att_type_name
mem_id
att_id
示例数据:

001 - Male - 001
002 - Female - 001
003 - Graduate - 002
004 - Masters - 002
005 - Engineer - 003
006 - Designer - 003
001 - Gender
002 - Education
003 - Profession
要填充查找下拉列表,我可以选择如下内容:

SELECT A.att_id, A.att_value, AT.att_type_name
FROM tbl_Attributes A
INNER JOIN tbl_Attribute_Types AT ON AT.att_type_Id = A.att_type_Id
WHERE att_Type_Id = @att_Type_Id
另外还有一个表
tbl_mem_att_value
,用于保存成员的属性和值

待确定成员附件值

mem_Id
mem_email
mem_password
Gender_Id
education_Id
profession_id
marital_status_Id
height_Id
residency_status_Id
att_Id
att_Value
att_Type_Id
att_type_Id
att_type_name
mem_id
att_id
成员_id 001的示例数据为男性、硕士、工程师

001 - 001
001 - 004
001 - 005
所以我的问题是我应该选择一个查找表还是多个查找表


谢谢

不要使用一个查找表来查找所有内容。这将使查找内容变得更加困难,并且可能需要在每个查询中加入多次,这意味着它可能会导致锁定和阻塞问题。此外,在一个表中,您不能使用良好的设计来确保描述符的数据类型是正确的。例如,假设您想要查找两个字符的州缩写。如果使用“一刀切”的表,那么它必须足够宽,以容纳任何查找中可能的最大值,并且您将失去拒绝错误条目的可能性,因为它太长了。这是以后数据完整性问题的保证。
此外,您不能正确使用外键来确保数据输入仅限于正确的值。这也会导致数据完整性问题


使用一个表除了几分钟的开发时间(可能是设计数据库时最不重要的问题)之外,没有任何好处。有很多负面因素

我自己也在为同样的问题挣扎。如果查找表中唯一的内容是某种代码或id和文本值,那么只需添加“属性id”并将其全部放入一个表中就可以了。明显的优点是,您只有一个表可以创建和管理。搜索可能会较慢,因为要搜索的记录较多,但您可能会在属性id+值id上创建索引。此时,使用一个大表还是十个小表可能会更好地提高性能,这取决于有关数据库引擎工作方式和访问模式的各种详细信息。在这种情况下,我会说,除非在实践中证明这是一个问题,否则不要担心

两个警告:

第一:如果创建一个表,我会为属性名创建一个代码,然后创建另一个表来列出代码。比如:

lookup_attribute(attribute_id, attribute_name)
lookup_value(attribute_id, value_id, value_text)
然后第一个表有如下记录

1, 'Gender'
2, 'Marital Status'
3, 'Education'
etc
第二个是

1, 1, 'Male'
1, 2, 'Female'
1, 3, 'Undecided'
2, 1, 'Single'
2, 2, 'Married'
2, 3, 'Divorced'
2, 4, 'Widowed'
3, 1, 'High School'
3, 2, 'Associates'
3, 3, 'Bachelors'
3, 4, 'Masters'
3, 5, 'Doctorate'
3, 6, 'Other'
etc.
(值id可能对所有属性id都是唯一的,也可能仅在属性id中是唯一的,只要对您有效。这不重要。)

第二:如果除了值的文本之外,还需要为某个属性存储其他数据,那么将其分解到单独的表中。比如说,如果你有一个属性,比如“会员级别”,然后用户说每个级别有不同的会费,你需要记录,那么你有一个额外的字段,只适用于这一个属性。在这一点上,它应该成为自己的桌子。我见过这样的系统,它们为几个属性中的每一个都有一些额外的数据,它们创建了一个名为“额外数据”或类似的字段,对于“会员级别”它包含年费,对于“门店名称”它包含门店所在的城市,对于“商品编号”它包含该商品的库存数量,等等,而这个系统很快就变成了一场噩梦

更新

为了检索值,假设我们只查找性别和婚姻状况。这一原则对任何其他人都是一样的

因此,我们有如上所述的怪物查找表。然后我们有一个成员表,比如

member (member_id, name, member_number, whatever, gender_id, marital_status_id)
要检索您,只需编写

select m.member_id, m.name, m.member_number, m.whatever,
  g.value_text as gender, ms.value_text as marital_status
from member m
join lookup_value g on g.attribute_id=1 and g.attribute_value=m.gender_id
join lookup_value ms on ms.attribute_id=2 and ms.attribute_value=m.marital_status_id
where m.member_id=@member_id
您也可以选择:

member (member_id, name, member_number, whatever)
member_attributes (member_id, attribute_id, value_id)
然后你可以得到所有的属性w

select a.attribute_name, v.value_text
from member_attribute ma
join lookup_attribute a on a.attribute_id=ma.attribute_id
join lookup_value v on v.attribute_id=a.attribute_id and v.value_id=ma.value_id
where ma.member_id=@member_id

当我试图编写查询时,我突然想到,使值id全局唯一有一个明显的优势:这不仅消除了在联接中指定属性id的必要性,而且还意味着如果您确实有一个字段,例如,gender_id,您仍然可以在其上有一个外键子句。

使用多个查找表的主要原因是您可以强制执行外键约束。这对于维护关系完整性非常重要


使用单个查找表的主要原因是,您可以将所有字符串值放在一个位置。这对于软件的国际化非常有用

通常,我会使用单独的引用表,因为关系完整性通常比国际化更重要

还有一些次要的考虑。许多不同的引用表将比单个引用表占用更多的空间——大多数页面都是空的(存储性别查找信息确实需要多少空间?)。然而,由于参考表的数量相对较少,这实际上是一个相当小的问题


使用单个表的另一个注意事项是,所有引用键都将具有不同的值。这很有用,因为它可以防止不可能的联接。但是,我通过为主键和外键命名相同的连接键来防止此问题。因此,
GenderId
将是
Gender
中的主键以及外键列。

将所有查找值放入一个