如果我有一个可以与多个密钥相关联的用户,则正确的表设置为:
一个包含两列的表,例如:
UserName | Key
其中没有主键,用户可以有多行,或者:
两个具有匹配标识符的表
Table 1 UserName | UserId
Table 2 Key | UserId
其中UserId
是table1的主键和表2的外键。
如果我想查找与用户关联的所有密钥,哪种方式更受欢迎?
答案 0 :(得分:2)
如果您想查找与给定用户关联的所有密钥,可以使用以下JOIN
查询:
SELECT Key
FROM keys k INNER JOIN users u
ON k.UserId = u.UserId
WHERE u.UserName = 'username'
在这种情况下,从索引中获益最多的地方将是两个表中的UserId
列。如果存在此索引,则对于给定用户,在Key
表中查找键将需要大致恒定的时间。
没有任何索引,MySQL将不得不为每个用户进行全表扫描,因为它试图找到与该用户相对应的密钥。
答案 1 :(得分:1)
在这种情况下,没有任何常见或不常见!这一切都取决于您的业务需求;如果用户可以拥有多个用户名,则需要有一个表格,将每个用户的所有这些用户名链接在一起,由userId
标识,此userId
应为因此,在整个数据库设计中用户的标识符,在这种情况下,您需要两个表:
UserDetails
将包含用户信息,例如姓名年龄...出生日期等,以及UserNames
,其中包含每个用户至少一个userName。
否则,您可以使用相同的表UserDetails
来存储userName以及其余的用户详细信息
因此,在您的情况下,使用单独的表来存储userNames,为什么在示例中:
假设您的用户有两个userName。
如果您使用一个表来存储userName的用户信息,您将获得如下数据:
Name BirthDate OtherDetails UserName AnotherDetails
user 1/1/1990 blah blah.. user1 blah blah...
user 1/1/1990 blah blah.. user2 blah blah...
如您所见,上表中的数据会重复
但是如果使用两个表,数据大小将会减少
答案 2 :(得分:1)
如果不了解您尝试建模的实体和属性,则无法回答您提出的问题。
实体关系建模
您的数据模型代表什么实体?实体是可以唯一标识的人,地点,事物,概念或事件,对系统很重要,我们可以存储有关的信息。
根据问题中的描述,我们认为"用户"是一个实体。也许"关键"也是一个实体。我们无法从描述中真实地说明这是一个实体,还是一个重复(多值)属性。
唯一标识"用户"?
的内容我们需要/想要存储哪些关于"用户"?
的属性第二部分是理解实体之间的关系。
为此,我们需要询问并获得一些问题的答案,例如:
有多少"用户"可以与特定的"键"?
相关联" key"必须与用户相关,或者密钥是否与零用户相关?
可以"键"除用户外,是否唯一标识?
等等。
基于这些答案,我们可以开始整理一个模型,并评估该模型表示问题的程度,以及该模型对我们预期用例的效果如何。
如果" user"和"关键"是实体,实体之间存在多对多关系,其模型看起来与“" key"不是实体,而只是一个多值属性。
如果某个密钥必须属于"一个且只有一个用户,用户可以"持有"零,一个或多个键,可能它是一个多值属性。然后我们需要两个表。一个父母"表"用户"实体和另一个孩子"用于存储重复属性的表。
我们还不知道(还)唯一标识用户的属性集,因此我们将使用通用" userid"来表示该属性。某种未指定数据类型的属性。
user
-----
userid datatype NOT NULL PRIMARY KEY
name varchar(30) NOT NULL
e.g。
userid name
------ ------
psimon paul simon
agarfu art garfunkel
为了存储多值属性,我们使用实体表的PRIMARY KEY作为我们第二个" child"中的外键。表
user_key
--------
userid datatype NOT NULL FOREIGN KEY ref user.userid
key VARCHAR(30) NOT NULL
e.g。
user_key
userid key
------- -------
psimon G major
psimon A major
psimon A major
psimon B minor
agarfu A major
如果我们决定"用户"将使用不同的列作为主键,然后我们将相同的列用作子表中的外键。
在这个例子中,我们允许"重复" "键"的值对于给定的用户。如果我们只想要"键"的明确值对于用户,我们需要在(userid, key)
元组上添加UNIQUE约束。
在我们过于担心性能之前,我们需要关注获得一些可行的数据模型。从那里,我们可以将其转化为一些实现,并评估每个实现的性能特征。
如果实施中的表没有合适的主键,我们可以引入另一列作为代理"主键。
答案 3 :(得分:0)
只要你的桌子有一个独特的PK,你就基本上是正确的,并在某些地方完成了#34;完美的"到"可以做得更好"。
在你的第一个案例中,你仍然是正确的,只是PK是UserName和Key。
第二个更常见,可能更正确,因为迟早你会想要与用户无关,并且在逻辑上适合UserName表的用户。