Как хранить псевдонимы в таблице базы данных - PullRequest
1 голос
/ 06 января 2011

Мне нужно иметь возможность искать возможные «псевдонимы» для заданного имени, но не могу понять, как правильно их хранить.

Например, допустим, что все перечисленные ниже формы имеют одно и то же имя:

Elizabeth, Eliza, Bessie, Beth, Betsy, Betty, Libby, Liza, Lisa, Liz, Lizzie 

Если пользователь наберет "Beth", я бы хотел получить все остальные псевдонимы из этого "набора".

Использование 20 (или более!) Столбцов с именем "Nickname1, Nickname2,..." кажется очень плохой идеей.

С другой стороны, ни одна из них по своей сути не будет основной записью других, поэтому нет ясного способа сделать ее реляционной / иерархической.

Я думал, что добавление столбца "GroupID" может сработать, а затем присвоить все имена в «наборе» тому же GroupID, но поле GroupID не будет иметь никакого другого значения, кроме группировки, и получение набора псевдонимов всегда требует вложенного запроса, например:

SELECT Name FROM Nicknames WHERE GroupID = (SELECT GroupID FROM Nicknames WHERE Name = 'Beth')

Не говоря уже о том, что для эффективной работы обоих столбцов в таблице должны быть свои собственные отдельные индексы.

Я что-то упустил? Кажется, это должно быть легко, но я не могу сегодня об этом думать.

(я использую SQL Server, но вопрос довольно общий, поэтому я не обозначил его как таковой).

Ответы [ 3 ]

4 голосов
/ 06 января 2011

Вы на правильном пути.И да, вам понадобится подзапрос или JOIN, чтобы получить результаты.

Если бы это был я, вместо использования целочисленного идентификатора группы я использовал бы формальную версию имени.Хитрость заключается в том, что вы должны включить отображение из формального имени в формальное имя.Таким образом, ваши значения будут выглядеть так:

 Name          FormalName
 ------------  -----------
 Elizabeth     Elizabeth
 Beth          Elizabeth
 Betsy         Elizabeth

Теперь, если пользователь даст вам «Бет», вы должны сделать:

 SELECT NT2.Name FROM NameTable NT1 INNER JOING NameTable NT2
    ON NT2.FormalName = NT1.FormalName AND NT1.Name = 'BETH'

Вы также можете создать представление следующим образом:

 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'

(оптимизатор должен сделать этот SELECT таким же эффективным, как и первый).

1 голос
/ 07 января 2011

Мне нравится пример, показанный здесь

http://answers.google.com/answers/main?cmd=threadview&id=251498

Поскольку это позволяет избежать проблемы, которая является более формальным именем, которое имеет решение Ларри Лустига.Если вы не хотите, чтобы каждое из псевдонимов также использовалось в качестве FormalName.

Group_no         Names
________         _____

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

Мне нравится это, потому что, если кто-то вводит Рика, он покажет им все имена групп 1 и 3.Но если кто-то будет Рикки, тогда они не получат таких нежелательных имен, как Дик

0 голосов
/ 06 января 2011

Да, вы правы, что никнейм1, никнейм2 и т. Д. Это плохая практика. Я бы не советовал НИКОГДА использовать это, если только вам не нужны только 2 и ваша 100% уверенность, что это никогда не изменится.

Похоже, у вас здесь есть основная запись: настоящее имя. По сути, вы можете оформить таблицы следующим образом:

Create Table Users(userID int, username varchar(20))
Create Table Nicknames(nicknameID int, name varchar(20), nickname(20))

Затем для каждого из этих псевдонимов в ваших примерах вам нужно будет вставить запись.

INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Elizabeth')
INSERT INTO Nicknames(name, nickname) VALUES('Beth', 'Eliza')
etc...

Тогда ваш запрос для их получения будет выглядеть примерно так:

Select nickname from Nicknames where name = 'Beth'

Возможно, вы сможете найти базу данных с такой информацией в Интернете, чтобы вам не приходилось создавать ее с нуля. Что-то вроде: http://www.peacockdata2.com/products/pdnickname/

...