2016-04-05 2 views
1

Если у меня есть пользователь, который может быть связан с несколькими ключами будет правильная настройка таблицы:Производительности первичного/внешнего ключ против одной таблицы с первичным ключом

  1. одна таблица с двумя столбцами, такими как:

    UserName | Key 
    

    где нет первичного ключа и пользователь может иметь несколько строк, или:

  2. две таблицы с идентификатором соответствия

    Table 1  UserName | UserId 
    
    Table 2  Key | UserId 
    

    где UserId является первичным ключом table1 и внешнего ключа таблицы 2.

Какой способ является более предпочтительным, если бы я хотел, чтобы найти все ключи, связанные с пользователем?

+3

*** КАЖДЫЙ *** стол должен иметь ** первичный ключ **! –

+4

Если у вас есть ** 1 ** пользователь с ** n ** ключами - правильный реляционный способ состоит в том, чтобы иметь ** две ** таблицы, которые связаны через общий столбец (например, 'userid'), как с надлежащим ** первичный ключ **, а второй подключен к первому через отношение внешнего ключа –

ответ

2

Если вы хотите, чтобы найти все ключи, связанные с данным пользователем вы можете использовать следующий JOIN запрос:

SELECT Key 
FROM keys k INNER JOIN users u 
    ON k.UserId = u.UserId 
WHERE u.UserName = 'username' 

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

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

0

Пока у вашего стола есть уникальный ПК, вы в основном правы и где-то по спектру «идеального», чтобы «мог сделать лучше».

В вашем первом случае вы все еще правы, просто, что PK является как UserName, так и Key.

Второй является более распространенным и, вероятно, более правильным, потому что рано или поздно вам понадобятся вещи против пользователей, которые не имеют никакого отношения к ключу и логически соответствуют таблице UserName.

1

Нет ничего общий или нестандартный в этом случае! все зависит от ваших бизнес-требований; Если у пользователя может быть несколько usernames, вам необходимо иметь таблицу для связывания всех этих имен пользователей для каждого пользователя вместе, идентифицированных userId, и этот userId должен быть идентификатором пользователя в вашем дизайне базы данных, поэтому вам нужно две таблицы в этом случае:

UserDetails, который будет содержать информацию о пользователе, такую ​​как возраст возраста ... дата рождения ... и т. д. и UserNames, который будет содержать по меньшей мере одно имя пользователя для каждого пользователя.

В противном случае, вы можете использовать ту же таблицу UserDetails хранить имя пользователя вместе с остальными деталями пользователя

Таким образом, в вашем случае, используйте отдельную таблицу для хранения USERNAMES, почему в качестве примера:

Предположим, у вас есть пользователь с двумя именами пользователей для него.

, если вы используете одну таблицу для хранения информации пользователя с именем пользователя, вы будете иметь ваши данные, как это:

Name  BirthDate  OtherDetails UserName AnotherDetails 
user  1/1/1990  blah blah.. user1 blah blah... 
user  1/1/1990  blah blah.. user2 blah blah... 

Как вы можете видеть, ваши данные в приведенной выше таблице повторяются

Но если вы использовали две таблицы, размер данных будет снижена

Это называется database normalization

1

Без понимания объектов и атрибутов, которые вы пытаетесь моделировать, на самом деле невозможно дать ответ на заданный вами вопрос.

Entity Relationship Моделирование

Что сущности ли ваша модель данных представляет? Сущность - это лицо, место, предмет, концепция или событие, которые могут быть однозначно идентифицированы, важно для системы, и мы можем хранить информацию о ней.

Из описания, данного в вопросе, мы думаем, что «пользователь» является сущностью. И, возможно, «ключ» также является сущностью. Мы не можем сказать из описания, является ли это сущностью, или является ли это повторяющимся (многозначным) атрибутом.

Что однозначно идентифицирует «пользователь»?

Какие атрибуты нам нужно/нужно хранить о «пользователе»?

Вторая часть понимает отношения между объектами.

Чтобы сделать это, мы должны спросить и получить ответы на некоторые вопросы, такие как:

Сколько «пользователи» могут быть связаны с определенным «ключ»?

Должен ли быть «ключ» связан с пользователем или может быть ключ связан с нулевыми пользователями?

Может ли «ключ» быть однозначно идентифицирован, кроме пользователя?

И так далее.

На основе этих ответов мы можем приступить к составлению модели и оценить, насколько хорошо эта модель представляет проблему, и насколько хорошо эта модель будет работать для наших ожидаемых вариантов использования.

Если «пользователь» и «ключ» являются сущностями, и между объектами существует взаимосвязь «многие-ко-многим», модель для этого будет выглядеть иначе, чем если «ключ» не является сущностью, но просто многозначный атрибут.

Если ключ должен «принадлежать» одному и только одному пользователю, а пользователь может «удерживать» ноль, один или несколько ключей, вероятно, это многозначный атрибут. Тогда нам нужны две таблицы. Одна «родительская» таблица для «пользовательской» сущности и другая «дочерняя» таблица для хранения повторяющегося атрибута.

Мы пока не знаем, какой набор атрибутов однозначно идентифицирует пользователя, поэтому мы будем представлять это с помощью общего атрибута «userid» некоторого неопределенного типа данных.

user 
----- 
userid datatype NOT NULL PRIMARY KEY 
name varchar(30) NOT NULL 

e.g.

userid name 
------ ------ 
psimon paul simon 
agarfu art garfunkel 

Для хранения многозначного атрибута A, мы используем первичный ключ таблицы объекта в качестве внешнего ключа в нашей второй таблице «ребенок».

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 

Если мы решим, что «пользователь» будет иметь другой столбец в качестве первичного ключа, то мы будем использовать тот же столбец в качестве внешнего ключа в дочерней таблице.

В этом примере мы разрешили «дублировать» значения для «ключа» для данного пользователя. Если нам нужны только отдельные значения «ключа» для пользователя, нам нужно добавить ограничение UNIQUE для кортежа (userid, key).


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

Если в реализации есть таблицы, которые не имеют подходящего первичного ключа, мы можем ввести другой столбец, который стоит в качестве «суррогатного» первичного ключа.

Смежные вопросы