Database design 如何在数据库表中存储昵称

Database design 如何在数据库表中存储昵称,database-design,normalization,Database Design,Normalization,我需要能够为一个给定的名字查找可能的“昵称”,但不能完全找出正确的存储方式 例如,假设以下所有形式的名称相同: Elizabeth, Eliza, Bessie, Beth, Betsy, Betty, Libby, Liza, Lisa, Liz, Lizzie 如果用户输入“Beth”,我希望能够检索此“集合”中的所有其他昵称 使用20个(或更多!)名为“昵称1,昵称2,…”的列似乎是一个非常糟糕的主意 另一方面,这些都不是其他的主记录,因此没有一个明确的方法来实现关系化/层次化 我在想

我需要能够为一个给定的名字查找可能的“昵称”,但不能完全找出正确的存储方式

例如,假设以下所有形式的名称相同:

Elizabeth, Eliza, Bessie, Beth, Betsy, Betty, Libby, Liza, Lisa, Liz, Lizzie 
如果用户输入“Beth”,我希望能够检索此“集合”中的所有其他昵称

使用20个(或更多!)名为
“昵称1,昵称2,…”
的列似乎是一个非常糟糕的主意

另一方面,这些都不是其他的主记录,因此没有一个明确的方法来实现关系化/层次化

我在想,添加一个
“GroupID”
列可能会起作用,然后将“set”中的所有名称分配给同一个
GroupID
,但是
GroupID
字段除了分组之外没有其他意义,并且获取一组昵称总是需要一个嵌套查询,如:

SELECT Name FROM Nicknames WHERE GroupID = (SELECT GroupID FROM Nicknames WHERE Name = 'Beth')
更不用说表中的两列都需要有自己的单独索引才能有效地工作

我错过什么了吗?这看起来应该很容易,但我今天没办法想清楚


(我使用的是SQL Server,但这个问题相当笼统,所以我没有将其标记为SQL Server)。

是的,您是正确的,昵称1、昵称2等都是不好的做法。我不会建议你使用它,除非你只需要2个,而且你的100%确信它永远不会改变

似乎你在这里有一个主记录:真实姓名。基本上,您可以按如下方式设计表格:

Create Table Users(userID int, username varchar(20))
Create Table Nicknames(nicknameID int, name varchar(20), nickname(20))
 CREATE VIEW NameMapping (OriginalName, NickName) AS 
 SELECT NT1.Name, NT2.Name FROM NameTable NT1 INNER JOIN NameTable NT2
    ON NT2.FormalName = NT1.FormalName
然后,对于示例中的每个昵称,您都需要插入一条记录

INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Elizabeth')
INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Eliza')
etc...
然后,检索它们的查询将类似于:

Select nickname from Nicknames where name = 'Beth'

您也可以在网上找到包含此类信息的数据库,这样就不必从头开始构建。类似于:

是的,你是对的,昵称1、昵称2等是不好的做法。我不会建议你使用它,除非你只需要2个,而且你的100%确信它永远不会改变

似乎你在这里有一个主记录:真实姓名。基本上,您可以按如下方式设计表格:

Create Table Users(userID int, username varchar(20))
Create Table Nicknames(nicknameID int, name varchar(20), nickname(20))
 CREATE VIEW NameMapping (OriginalName, NickName) AS 
 SELECT NT1.Name, NT2.Name FROM NameTable NT1 INNER JOIN NameTable NT2
    ON NT2.FormalName = NT1.FormalName
然后,对于示例中的每个昵称,您都需要插入一条记录

INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Elizabeth')
INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Eliza')
etc...
然后,检索它们的查询将类似于:

Select nickname from Nicknames where name = 'Beth'

您也可以在网上找到包含此类信息的数据库,这样就不必从头开始构建。类似于:

你走对了方向。是的,您将需要一个子查询或联接来获得结果

如果是我,我会使用正式版本的名称,而不是使用整数组ID。诀窍是必须包含从正式名称到正式名称的映射。因此,您的值将如下所示:

 Name          FormalName
 ------------  -----------
 Elizabeth     Elizabeth
 Beth          Elizabeth
 Betsy         Elizabeth
现在,如果用户给你“Beth”,你会:

 SELECT NT2.Name FROM NameTable NT1 INNER JOING NameTable NT2
    ON NT2.FormalName = NT1.FormalName AND NT1.Name = 'BETH'
还可以按如下方式创建视图:

Create Table Users(userID int, username varchar(20))
Create Table Nicknames(nicknameID int, name varchar(20), nickname(20))
 CREATE VIEW NameMapping (OriginalName, NickName) AS 
 SELECT NT1.Name, NT2.Name FROM NameTable NT1 INNER JOIN NameTable NT2
    ON NT2.FormalName = NT1.FormalName
然后

 SELECT NickName FROM NameMapping WHERE OriginalName = 'BETH'

(优化器应使此选择与第一个选择一样有效)。

您的选择是正确的。是的,您将需要一个子查询或联接来获得结果

如果是我,我会使用正式版本的名称,而不是使用整数组ID。诀窍是必须包含从正式名称到正式名称的映射。因此,您的值将如下所示:

 Name          FormalName
 ------------  -----------
 Elizabeth     Elizabeth
 Beth          Elizabeth
 Betsy         Elizabeth
现在,如果用户给你“Beth”,你会:

 SELECT NT2.Name FROM NameTable NT1 INNER JOING NameTable NT2
    ON NT2.FormalName = NT1.FormalName AND NT1.Name = 'BETH'
还可以按如下方式创建视图:

Create Table Users(userID int, username varchar(20))
Create Table Nicknames(nicknameID int, name varchar(20), nickname(20))
 CREATE VIEW NameMapping (OriginalName, NickName) AS 
 SELECT NT1.Name, NT2.Name FROM NameTable NT1 INNER JOIN NameTable NT2
    ON NT2.FormalName = NT1.FormalName
然后

 SELECT NickName FROM NameMapping WHERE OriginalName = 'BETH'

(优化器应使此选择与第一个选择一样有效)。

我喜欢这里显示的示例

因为这避免了拉里·卢斯蒂格解决方案的更正式名称的问题。除非你想把每个昵称也作为正式名称

Group_no         Names
________         _____

1                Richard
1                Rick
1                Dick
1                Ric
2                Steve
2                Steven
2                Stephen
3                Ricky
3                Rick
3                Ric

我喜欢这个,因为如果有人输入Rick,它会显示所有组1和组3的名称。但是如果有人输入Ricky,那么他们就不会得到像Dick这样不需要的名字了

我喜欢这里的例子

因为这避免了拉里·卢斯蒂格解决方案的更正式名称的问题。除非你想把每个昵称也作为正式名称

Group_no         Names
________         _____

1                Richard
1                Rick
1                Dick
1                Ric
2                Steve
2                Steven
2                Stephen
3                Ricky
3                Rick
3                Ric

我喜欢这个,因为如果有人输入Rick,它会显示所有组1和组3的名称。但是,如果有人进入瑞奇的话,他们就不会以迪克这样不受欢迎的名字结束。

难道《伊丽莎白》本身就不是其他人的“大师”唱片吗?@derobert:“情妇”,我想,不是吗?查一下,然后做些什么?你是否在尝试构建一些重复数据消除软件?在这个时代,我会非常自觉地创建一个名为Formal_Name的专栏,并填充该专栏。安妮不是安的更正式的版本。。。Joann、Annabelle、Annabeth也不是。。。请看这里。这些是真实的名字,而不是昵称。有一些人叫杰克,尽管这也是约翰的一个刻痕。这就是为什么我问你要用“翻译”做什么。如果这是用于后端处理(如重复数据消除),那么我会得到它,但我只会购买一个已经做到这一点的组件。“Elizabeth”不是天生就是其他的“主”记录吗?@derobert:“情妇”,我想,不是吗?查找它们,然后对它们做些什么?你是否在尝试构建一些重复数据消除软件?在这个时代,我会非常自觉地创建一个名为Formal_Name的专栏,并填充该专栏。安妮不是安的更正式的版本。。。Joann、Annabelle、Annabeth也不是。。。请看这里。这些是真实的名字,而不是昵称。有一些人叫杰克,尽管这也是约翰的一个刻痕。这就是为什么我问你要用“翻译”做什么。如果这是用于后端过程,比如重复数据消除,那么我就可以得到它,但我只想买一个已经完成了这项工作的组件。哪一个是主组件?乔治还是乔治?它们在各自的语言中都是完全正确的(正式名称)。没关系,只需选择一种(可能是系统编写的语言)。用户使用的是单一语言,而不是i18n。但是同样的sc