Есть ли основания беспокоиться о порядке столбцов в таблице? - PullRequest
77 голосов
/ 21 мая 2009

Я знаю, что вы можете ИЗМЕНИТЬ порядок столбцов в MySQL с помощью FIRST и AFTER, но зачем вам это беспокоить? Поскольку в хороших запросах при вставке данных явно указываются имена столбцов, есть ли какая-то причина заботиться о том, в каком порядке находятся ваши столбцы в таблице?

Ответы [ 13 ]

89 голосов
/ 21 мая 2009

Порядок столбцов оказал большое влияние на производительность некоторых из настроенных мной баз данных, включая Sql Server, Oracle и MySQL. В этом посте хорошие эмпирические правила :

  • Первичные ключевые столбцы сначала
  • Следующие столбцы внешнего ключа.
  • Часто просматриваемые столбцы далее
  • Часто обновляемые столбцы позже
  • Последние столбцы, имеющие значение Nullable.
  • Меньше всего используемых столбцов, допускающих значение NULL, после более часто используемых столбцов, которые могут иметь значение NULL

Примером различий в производительности является поиск по индексу. Механизм базы данных находит строку, основанную на некоторых условиях в индексе, и возвращает адрес строки. Теперь скажите, что вы ищете SomeValue, и он находится в этой таблице:

 SomeId int,
 SomeString varchar(100),
 SomeValue int

Движок должен угадать, где начинается SomeValue, потому что SomeString имеет неизвестную длину. Однако, если вы измените заказ на:

 SomeId int,
 SomeValue int,
 SomeString varchar(100)

Теперь движок знает, что SomeValue можно найти через 4 байта после начала строки. Таким образом, порядок столбцов может оказать значительное влияние на производительность.

РЕДАКТИРОВАТЬ: Sql Server 2005 хранит поля фиксированной длины в начале строки. И в каждой строке есть ссылка на начало varchar. Это полностью сводит на нет эффект, который я перечислил выше. Так что для последних баз данных порядок столбцов больше не влияет.

39 голосов
/ 21 мая 2009

Обновление:

В MySQL может быть причина для этого.

Поскольку типы переменных (например, VARCHAR) хранятся с переменными длинами в InnoDB, ядро ​​базы данных должно пройти по всем предыдущим столбцам в каждой строке, чтобы узнать смещение заданного.

Воздействие может быть таким большим, как 17% для 20 столбцов.

См. Эту запись в моем блоге для более подробной информации:

В Oracle конечные столбцы NULL не занимают места, поэтому всегда следует помещать их в конец таблицы.

Также в Oracle и в SQL Server, в случае большого ряда, может возникнуть ROW CHAINING.

ROW CHANING разбивает строку, которая не умещается в один блок, и охватывает ее по нескольким блокам, связанным со связанным списком.

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

См. на этой странице для иллюстрации ROW CHAINING in Oracle:

Вот почему вы должны помещать столбцы, которые вы часто используете, в начало таблицы, а столбцы, которые вы не используете часто, или столбцы, которые обычно равны NULL, - в конец таблицы.

Важное примечание:

Если вам нравится этот ответ и вы хотите проголосовать за него, пожалуйста, также проголосуйте за @Andomar ответ .

Он ответил тем же, но, кажется, голосовал без причины.

6 голосов
/ 21 мая 2009

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

В общем, это не должно иметь никакого значения. Как вы говорите, запросы должны всегда указывать сами столбцы, а не полагаться на порядок из "select *". Я не знаю ни одной БД, которая позволяла бы их изменять ... ну, я не знал, что MySQL разрешил это, пока вы не упомянули это.

5 голосов
/ 21 мая 2009

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

5 голосов
/ 21 мая 2009

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

Марк

РЕДАКТИРОВАТЬ: из записи в Википедии по реляционной базе данных, вот соответствующая часть, которая мне ясно показывает, что порядок столбцов никогда не должен вызывать беспокойство:

Отношение определяется как набор n-кортежей. Как в математике, так и в модели реляционной базы данных набор представляет собой неупорядоченный набор элементов , хотя некоторые СУБД навязывают порядок своим данным. В математике кортеж имеет порядок и допускает дублирование. Э. Ф. Кодд первоначально определил кортежи, используя это математическое определение. Позднее Э. Ф. Кодд понял, что использование имен атрибутов вместо упорядочения будет намного удобнее (в общем) на компьютерном языке, основанном на отношениях. Это понимание все еще используется сегодня.

4 голосов
/ 21 мая 2009

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

select * from <table>

в вашем программном обеспечении для управления базами данных?

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

2 голосов
/ 21 мая 2009

Единственная причина, по которой я могу думать, это отладка и пожаротушение. У нас есть таблица, столбец которой «имя» появляется примерно 10-й в списке. Это неприятно, когда вы делаете быстрый выбор * из таблицы, где id в (1,2,3), а затем вам нужно прокрутить список, чтобы посмотреть на имена.

Но это все.

1 голос
/ 08 декабря 2016

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

Из документации "столбцы TIMESTAMP и DATETIME не имеют автоматических свойств, если они не указаны явно, за исключением следующего: по умолчанию первый столбец TIMESTAMP имеет как DEFAULT CURRENT_TIMESTAMP, так и ON UPDATE CURRENT_TIMESTAMP, если ни один из них не указан явно" https://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html

Итак, команда ALTER TABLE table_name MODIFY field_name timestamp(6) NOT NULL; будет работать, если это поле является первой отметкой времени (или datetime) в таблице, но не иначе.

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

1 голос
/ 21 мая 2009

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

1 голос
/ 21 мая 2009

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

...