Как эффективен способ маркировки столбцов в базе данных?

30

Я использовал для обозначения столбцов в моих базах данных, как это:

user_id
user_name
user_password_hash

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

Какой эффективный способ маркировки столбцов в базе данных? Зачем?

Томас О
источник
Какая база данных? То, как я помечаю в Oracle, отличается от большинства других баз данных тем, что он позволяет автоматически выбирать столбцы для базовых объединений, если имена совпадают.
Джо
@Joe, ну, я всегда использовал MySQL и SQLite3, но это должно относиться к большинству других баз данных.
Томас О
@joe никогда не замечал, что Oracle отличается. Можете дать ссылку?
bernd_k
@bernd_k: Я добавил несколько ссылок на свой ответ , ниже
Джо

Ответы:

33

В вашем случае префикс пользователя является избыточным. Мы (ответственные разработчики) знаем, что это пользователь таблицы, так зачем добавлять user_префикс перед каждым полем?

Я бы предложил вам сделать это с более естественным подходом.

Каковы характеристики человека: фамилия, имя, дата рождения, национальность и т. Д ...

Каковы характеристики автомобиля: модель, год, цвет, энергия и т. Д ...

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

Spredzy
источник
1
Да, меня бесит, когда люди так делают. Также, когда они называют всю свою таблицу tbl_whither.
Гай
Это также относится к понятию «Слова класса», и в сообществе, кажется, есть некоторые споры, когда «Слова класса» подходят и не подходят. (Слово класса - это инструмент для: определения отдельной категории или классификации данных, определения типа данных, описываемых именем данных, и описания основной классификации данных, связанных с элементом данных.)
Джон Шонинг,
17

В дополнение к комментарию Spredzy, пометьте свои первичные ключи одинаково (ID), чтобы при написании запросов на лету вы могли легко вызывать (u.ID = c.ID) вместо необходимости искать «Было ли это countryID» , идентификатор страны, идентификатор страны, идентификатор страны,? "

Дэвид Холл
источник
5
Однажды я работал над базой данных, где администратор БД решил использовать идентификатор в некоторых таблицах и идентификатор в других, и мы настроили MySQL так, чтобы он учитывал регистр ... забавные времена!
Тоби
6
Мы обычно используем tablename.tablename_id. Например, car.car_id; person.person_id. Особые имена для таблиц.
Glasnt
@ гласное умное решение.
Гарик
1
На самом деле это очень плохая идея, и вы потеряете возможность использовать предложение SQL USING(это противоречит спецификации).
Эван Кэрролл
9

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

Нет смысла иметь users.user_id и cars.car_id, когда вы можете иметь users.id и cars.id

bsoist
источник
7

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

  • С точки зрения моделирования: вы начинаете с супа атрибутов и нормализуете его в таблицы. Со временем вы можете денормализовать или нормализовать дальше или представить представления или материализованные представления, или представить новые таблицы. Это никогда не проблема, если все имена столбцов уникальны.

  • Вы можете использовать этот синтаксис объединения: a JOIN b USING (a_id) JOIN c USING (a_id). Очень удобно, а также помогает в следующем.

  • Если вы выполняете запросы с большим количеством объединений или создаете материализованные представления SELECT *, у вас никогда (ну, может быть, редко) не возникнет конфликта. Подумайте о присоединении person.name, product.name, country.nameи т.д. Urgh.

  • В общем, если у вас большие запросы, сложно отследить, что это idзначит везде.

Питер Айзентраут
источник
Как бы вы назвали столбец для имени сотрудника и имени сайта, например? Как бы вы избежали избыточности столбца метки имени?
Spredzy
@Spredzy: Я бы просто пошел с избыточностью.
Питер Айзентраут
1
Ответ на эти проблемы: псевдонимы.
Джон на все руки
7

Давайте посмотрим, на вашем примере это будет выглядеть примерно так:

USERS
----
id
username,
password
registration_date

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

Кстати, я думаю, вы должны найти какой-то стиль, который вам нравится, и придерживаться его. Если вы будете часто его менять, то у вас будет более сложная схема БД.

eiefai
источник
+1 за «найди какой-нибудь стиль, который тебе нравится, и придерживайся его». Согласованность лучше, чем точное соответствие с каким-либо конкретным стандартом (хотя, если вы еще не выбрали стандарт, некоторые лучше, чем другие).
Джон на все руки
5

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

Недавно я покинул компанию, в которой один из разработчиков предпочитал добавлять к столбцам первичного ключа и внешнего ключа префикс pk и fk. Это привело к некоторым мерзостям, когда столбцы начинались с pkfk (обычно составной первичный ключ, основанный на 2 столбцах, из которых один столбец был внешним ключом для другой таблицы).

Tangurena
источник
4
это считается как fk_cluster?
Кадзи
5

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

В идеале имена столбцов уникальны для всех таблиц в базе данных.

Некоторые наблюдения:

  • нам нужны только псевдонимы таблиц, когда таблицы объединяются несколько раз в операторе выбора
  • это предотвращает некоторые ошибки при копировании фрагментов кода, потому что имена столбцов должны быть адаптированы к имени таблицы
  • помогает показать, на какую таблицу указывает столбец внешнего ключа

Общие идеи: Наиболее важным является согласованность каждого соглашения об именах: - единственное и множественное число (хорошо, что относится к таблицам, а не к столбцам) - идентифицируют первичные и внешние ключи (они строят структуру по сравнению с содержимым базы данных) - должны быть согласованы, когда Вы храните строки и короткие варианты одной и той же строки - будьте совместимы с флагами, статусом и т. д.

bernd_k
источник
3

Я согласен с ответом Спредзи, но добавил бы, что я бы предпочел использовать camelCase вместо under_score.

имя, фамилия и т. д.

Тоби
источник
2
-1, потому что CamelCase работает не во всех системах баз данных, а вы не указали систему баз данных. Например, плохая новость - использовать CamelCase в Oracle (для его создания потребовалось бы использовать двойные кавычки, но с тех пор каждый, кто обращается к нему, должен был бы перепрыгивать через обручи, чтобы получить к нему доступ). Какой кошмар.
ScottCher
@ ScottCher - я не знал, что это не работает в Oracle, но я не являюсь администратором базы данных Oracle. Я бы подумал, что будет принято как данность, что имена столбцов должны сначала соответствовать правилам, установленным рассматриваемой DBS.
Тоби
3

В случае Oracle, вы хотите , чтобы не назвать столбцы «идентификатор» или «имя» или что - нибудь родовое.

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

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

SELECT
  instrument.name as instrument_name,
  instrument.abbr as instrument_abbr,
  source.name     as source_name,
  source.abbr     as source_abbr,
  ...
FROM ...

Таким образом, если выбор из нескольких таблиц является нормой, более длинные имена столбцов сохраняют ваш ввод. (если вы используете только одну таблицу за раз ... вам действительно нужна реляционная база данных?)

... и сохранение типизации приводит нас к другой проблеме в Oracle - по крайней мере, в 8i (текущая версия, когда я проходил курсы по настройке Oracle SQL Tuning и Data Modeling), кэширование планов выполнения основано только на первых, стольких символах запрос (не могу вспомнить точное значение ... 1024?), поэтому, если у вас есть запросы, которые только в чем-то меняются в конце предложения where, и действительно длинный список столбцов, которые вы извлекаете, вы может привести к падению производительности, поскольку не может правильно кэшировать план выполнения.

У Oracle было руководство по выбору того, что они называют хорошими именами таблиц и столбцов, в основном это руководство по удалению букв до 5-8 символов, но меня это мало заботило.

...

Как дела идут иначе, чем это:

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

обновление : для тех, кто не знаком с поведением соединения Oracle, смотрите последний пример « Освоение Oracle SQL: условия соединения» , где упоминается:

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

В «старом синтаксисе соединения» (8i и более ранних) «NATURAL JOIN» было поведением соединения по умолчанию, и я верю, что это так и есть, если вы не указали условие соединения. Когда в 9i «NATURAL JOIN» был официальным вариантом, общая рекомендация заключалась в том, чтобы не использовать его , потому что неправильное именование столбцов может вас испортить, что я и рекомендую для хороших имен столбцов.

Джо
источник
4
Вы имеете в виду "Natural Joins" во втором абзаце? Если это так SHUDDER ... Когда это возможно, вы должны указать, как вы хотите, чтобы ваша система баз данных присоединилась к вашим таблицам. Передача данных в базу данных может привести к неожиданным / противоречивым результатам. Кроме того, естественные объединения ограничены объединениями между двумя таблицами и, следовательно, относительно ограничены в их удобстве использования.
ScottCher
2
ЕСТЕСТВЕННОЕ СОЕДИНЕНИЕ никогда не было по умолчанию. Если явного объединения не было / было дано, было бы выполнено декартово соединение (т. Е. Каждая строка в таблице, соединенная с каждой строкой в ​​другой таблице). До того, как будут поддержаны объединения ANSI (т. Е. Указанные в предложении FROM), объединения должны были быть выполнены в предложении WHERE.
Гари
1
-1 для естественных объединений. Когда несвязанное изменение схемы может разорвать соединения или, что еще хуже, изменить их без каких-либо ошибок, вас ждет мир боли. Пожалуйста, подумайте о детях, и ВСЕГДА указывайте ваши поля присоединения.
Джон на все руки
2
@ScottCher: «Оставить это на усмотрение базы данных» - во-первых, вероятно, вы имеете в виду «СУБД», а не «база данных». Во-вторых, в Oracle нет ни AI, ни антропоморфического механизма; скорее, NATURAL JOINявляется детерминированным.
onedaywhen
1
@Joe cross joinесть, был и всегда будет «по умолчанию». Oracle никогда не совпал по имени столбца, если не natural joinбыл явно использован
Джек Дуглас
1
  1. Никогда не используйте двойные кавычки, "потому что при этом вы переопределяете собственное свертывание регистра базы данных. Спецификация SQL требует, чтобы все идентификаторы были заглавными. Некоторые базы данных, такие как PostgreSQL, сворачивают их в нижний регистр. Если ничего не заключено в кавычки, это сработает во всех базах данных, и они могут свернуть их в спецификацию или специфичное для rdbms значение по умолчанию.
  2. Используйте under_score ( _), потому что, как указано выше, вы не должны использовать camelCase.
  3. использовать {entity}_idдля идентификаторов (и внешние ключи, указывающие на эти идентификаторы). Потому что тогда вы можете использовать USINGпредложение. Глобально уникальные имена ключей, используемые в условиях соединения, являются соглашением, установленным в спецификации.

    SELECT *
    FROM employee
    INNER JOIN department
      USING (department_id);
    
      -- compare to
      ON employee.department_id = department.department_id;
Нил Макгиган
источник
1
Я обновил это, чтобы быть более явным.
Эван Кэрролл