LINUX.ORG.RU

Используете ли вы генерацию первичных ключей таблиц БД с помощью триггеров?

 ,


0

2

Смысл в том, что обычно первичный ключ таблицы делается в виде целого числа, которое увеличивается при вставке строки с данными на единичку. Во многих СУБД есть встроенные генераторы типа AUTOINCREMENT, SERIAL и так далее, однако это привязывает схему к конкретной СУБД плюс возможны сбои при миграциях.

Альтернатива — делать первичный ключ просто как целое число и вешать на таблицу функцию, которая увеличивает это число при вставке строки.

  1. Нет, использую встроенные типы 142 (48%)

    ********************************************************************************************************************************************************************************************************************************************************************************************************************************

  2. Не работаю с БД 137 (46%)

    ********************************************************************************************************************************************************************************************************************************************************************************************************************

  3. И так сойдет! 31 (11%)

    *********************************************************************

  4. Уже перешел (напишите как и почему) 5 (2%)

    ***********

  5. Нет, задумываюсь о переходе на триггеры для переносимости кода 3 (1%)

    ******

  6. Нет, задумываюсь о переходе из-за проблем с автогенерацией ключа (напишите, из-за каких) 2 (1%)

    ****

Всего голосов: 320, всего проголосовавших: 295

★★★★★

Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 4)

привязывает схему к конкретной СУБД

Никогда не понимал, зачем постоянно переносить базу на разные СУБД. Сам себе отрезаешь 90% важных и полезных фич, оставляешь тупейшие таблицы, даже serial вон нормально не переносится. И ради чего в итоге? Кому это нужно?

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

neumond ★★
()
Ответ на: комментарий от LongLiveUbuntu

То, что однажды нам прислали новую версию СУБД, мы ее установили, раскатали скриптом БД из бэкапа и первичные ключи грохнулись

Эт чё за СУБД такая замечательная? Назови имя, народ должен знать своих героев. Ломать автоинкремент обновлениями это какой-то новый уровень.

Ну а в целом, как я уже говорил, подобные вещи это наименьшая проблема при миграции на другую СУБД. На сколько я понимаю аналогичные до степени смешения фичи есть почти во всех РСУБД

MrClon ★★★★★
()
Ответ на: комментарий от mumpster

Я иногда заглядываю в неподтвержденные опросы, чтобы на главной висела любительская социология, а не «Вы перестали пить коньяк по утрам?», «Стоят два стула…», китайский классификатор животных и т. п. Да и бывает, что автор забыл в нормальном опросе какой-то важный пункт.

ну значит тебе этот вопрос был вообще не нужен. )))

Ну да, «тебя не спрашивали, проходи мимо», «это мой опрос, я так вижу, а ты создай свой»…

ну или последний пункт.

Который добавил @hobbit уже позже.

Vidrele ★★★★★
()

а что так можно было?

jura12 ★★★
()
Ответ на: комментарий от Aceler

У autoincrement'а, а также в принципе монотонных числовых id есть проблема, что нельзя взять дамп одной БД и влить его в другую, где уже есть какие-то данные (хотя бы одна строчка), так как будет конфликт id. В этом плане рулят UUID.

Ещё монотонные числовые id прокинутые наружу уязвимы к перебору (если мы не хотим давать юзерам угадывать id сущностей) + выдают примерное количество записей в таблице. Опять же, тут рулят UUID.

С другой стороны, не всем это, конечно же, важно, а UUID менее читабельны и потенциально чуть тяжелее индексы выходят и внешние ключи (16 байт вместо 4-8 байт, но, говорят, на современном железе и реальных данных это уже не играет роли).

Что касается же портабельности миграций между СУБД это нужно разве что всяким универсальным комбайнам типа Joomla и Wordpress.

Если речь о разработке чего-то бизнесового (в смысле для конечного пользователя, а не от разработчиков для разработчиков), то там практически всегда привязка к конкретной СУБД не проблема, плюс нужны vendor-specific оптимизации (разве что если СУБД используется как тупое key-value хранилище, но тогда может быть лучше посмотреть на NoSQL), при этом денег на полное тестирование (соблюдать стандарт SQL недостаточно, потому что, например, валидный SQL код может тупо тормозить на конкретной БД в силу особенностей её реализации, об этом надо как-то узнать, да и вообще движки местами нарушают стандарт) на всех существующих СУБД никто не даст.

Но ТС упустил тот факт, что синтаксис триггеров и пользовательских функций варьируется от СУБД к СУБД, а где-то их вообще может не быть.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 4)
Ответ на: комментарий от stave

https://www.google.com/amp/s/habr.com/ru/amp/publications/572700/

Ты сам-то статью читал?

Ну вот например

Я написал свою имплементацию на Golang. Эта очень странная версия, рассчитанная на то, что стандарт будет меняться, соответственно количество бит в каждом поле может измениться.

Какая нахрен имплементация?

Есть общепринятый SQL-запрос, прям классика: SELECT FROM table ORDER BY id. Вот и расскажи мне как не-INT поле собралось сортироваться по дате добавления.

Так чтоб я не писал свои реализации какой-то ненужной фигни.

windows10 ★★★★★
()
Ответ на: комментарий от Dimez

Ты серьёзно? В одном сообщении пишешь про 15-20Gb и тут же рядом в другом про phpmyadmin dump? :))

Что именно тебя смущает?

В PMA заходишь в экспорт, нажимаешь Go и качаешь хоть 100 гиговый дамп.

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

Видишь ли, не все люди в этом мире, чтобы открыть интернет-магазин для продажи котиков, изучают всякие Go, поднимают инфраструктуру уровня пентагона с микросервисами и логами. Исходя из своего опыта, я бы даже сказал что таких меньшинство, остальные берут Magentу, Prestashop или даже Wordpress и у них все работает.

windows10 ★★★★★
()

Лет 20 тому, когда начинали свою ORM, пытались возложить генерацию PK на СУБД (на первый взгляд оно было удобно и красиво). Но в итоге, пройдясь по полю граблей, пришли к тому, что при таком использовании доверять ей это категорически нельзя. Этим должен заниматься сервер приложений. А в особо запущенных случаях — специально обученный сервис, у которого серверы приложнений будут запрашивать диапазоны PK.
Так что без уточнения назначения БД опрос особого смысла не имеет.

KOHb-TPOJIJIbJIEP ★★
()
Ответ на: комментарий от windows10

если тебе нужно сортировать по дате добавления так и сортируй по полю с датой, закладываться на айди - стрелять себе в ногу

masa ★★★
()
Ответ на: комментарий от masa

если тебе нужно сортировать по дате добавления так и сортируй по полю с датой, закладываться на айди - стрелять себе в ногу

Если мне нужно заводить поля с датой - значит UUIDы мне тем более не нужны, достаточно простого AI.

windows10 ★★★★★
()

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

pfg ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

То, что однажды нам прислали новую версию СУБД, мы ее установили, раскатали скриптом БД из бэкапа и первичные ключи грохнулись, такие дела. Плюс контора может тысячу и один год работать с MS SQL, а тут MS уходит и срочно надо мигрировать на что-то еще. Например.

Ну как ты видишь по результатам опроса, большинство (и я тоже) юзают встроеный автоинкремент и в ус не дуют, так что более конструктивно было бы описать какие именно проблемы возникают на каких конкретно СУБД, а то мужики не знают. @KOHb-TPOJIJIbJIEP

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 2)
Ответ на: комментарий от windows10

А как инт поле зависит от даты добавления? И в чем вообще проблема с сортировкой полей, строки что-ли не сортируются? Ты не попутал часом в чем смысл уникального ключа?

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

stave ★★★★★
()
Ответ на: комментарий от windows10

В PMA заходишь в экспорт, нажимаешь Go и качаешь хоть 100 гиговый дамп.

Но… Зачем выбирать самый тупой и максимально ненадёжный вариант???

Dimez ★★★★★
()
Ответ на: комментарий от Dimez

Для большой БД только mysqldump на сервере

Это куда нужно зайти\нажать, чтобы открылась эта менюшка?

windows10 ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

Предположим, СУБД не поддерживает UUIDv7. Твои действия?

Что тебе мешает генерировать UUID на клиенте?

Rodegast ★★★★★
()

Как говорили древние — keep it simple, stupid.

urxvt ★★★★★
()
Ответ на: комментарий от KivApple

нельзя взять дамп одной БД и влить его в другую, где уже есть
какие-то данные
можно. прост требуется доп.работа по переделке id причём не особо сложная, к id из первой базы +прибавлять max(id) из второй

mumpster ★★★★★
()
Ответ на: комментарий от masa

намёк, что не мешало бы смотреть на вещи чуть шире, начиная с данных, а не зацикливаться на рюшечках. С серьёзным видом срутся о реализации автоинкремента, как дети, ей-богу. Даже при «ужасном» переходе на другую БД перенастройка генерации ID - это доли процента от общих трудозатрат…

EAT_INSIDE
()
Последнее исправление: EAT_INSIDE (всего исправлений: 1)
Ответ на: комментарий от mumpster

прост требуется доп.работа

Здорово, всего лишь все ID и сиквенсы перелопатить, не забыв отследить места, где нет внешних ключей, плюс проверить, что во внешних системах на них никто не завязан. И на всё время между снятием дампа и слиянием заблокировать изменение данных в принимающей БД, чтобы счётчики не изменились.

EAT_INSIDE
()
Последнее исправление: EAT_INSIDE (всего исправлений: 1)

это привязывает схему к конкретной СУБД

а что за софт? нужно уметь поддерживать сразу кучу баз одновременно, и поэтом sql упрощается до некого подмножества что одинаков везде?

oxo
()
Ответ на: комментарий от EAT_INSIDE

Ты похоже похоже совсем не понял меня

masa ★★★
()
Ответ на: комментарий от EAT_INSIDE

если тебя это пугает - то что ты здесь делаешь?

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

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

похоже, что ты просто не очень понимаешь что требуется сделать.

mumpster ★★★★★
()
Ответ на: комментарий от oxo

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

единственная проблема была с interbase (там нет в привычном виде seq)

mumpster ★★★★★
()
Ответ на: комментарий от mumpster

что ты здесь делаешь

Кринжую, глядя на вас, в целом.

блокировать изменения в принимающей не требуется

В описанном подходе требуется, иначе max(id) изменится.

EAT_INSIDE
()
Ответ на: комментарий от EAT_INSIDE

я лично оспариваю требование

И на всё время между снятием дампа и слиянием заблокировать

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

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

реализуемо на баше, PS и большинстве нормальных ЯП включая php -для ЦА в лице

[user]windows10[/user]

mumpster ★★★★★
()
Последнее исправление: mumpster (всего исправлений: 1)
Ответ на: комментарий от oxo

У него синдром юзера шаред-хостинга из 2000-х, который заранее не знал, какие версии пхп и mysql окажутся на очередном шаред-хостинге, выбранном по принципу «лишь бы подешевле» и поэтому в своих свкриптах поддерживал их все сразу. Теперь, судя по нежеланию использовать автоинкремент, род деятельности уже сменился (на шаред-хостингах ничего кроме mysql не бывает, и автоинкремент там всегда есть), но вот привычки остались старые.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от EAT_INSIDE

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

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

это привязывает схему к конкретной СУБД

ЯППН а триггеры не привязывают? Там вообще всё везде по разному.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Вообще-то это стандарт как раз, еще с хрен какого года.

LongLiveUbuntu ★★★★★
() автор топика

никак не проголосовал, т.к. считаю что мнемотип а ля оракловский sequence обязан быть в стандарте SQL, хоть big-very-very-big unsigned unique int, хоть GUID - хоть в тексте, хоть в числе.
ну и где используется - быть уникальным в рамках кластера, и наверное - достаточно быстрым?

etwrq ★★★★★
()

По всякому приходилось делать. Иногда надо чтоб ключ был не просто числом или числом не простым. Но обычно инкремента достаточно. Для миграций я таким точно не стал бы заморачиваться. Вот если по данным что-то интересное происходит что ключ на них основан, то да, можно.

peregrine ★★★★★
()
Ответ на: комментарий от ya-betmen

Дёргаются когда не берут БД на вырост сразу. Ну например берут Sqlite какой-то или мускуль, но понимают что если проект взлетит, то надо будет брать постгри или оракл или даже вообще думать про более специфичные БД которые будут типичную нагрузку держать.

peregrine ★★★★★
()
Ответ на: комментарий от neumond

Ну смотри, например, у тебя может быть условно-бесплатное приложение веб-сервис. На твоём серваке крутится мощная субд, вроде постгри. И она тянет 100500 пользователей ресурса. А ещё ты делаешь завёрнутое в электрон или просто локальный веб-сервер, например апач томкат приложение для конечных юзеров, которые не хотят свои данные тебе в облако лить и хотят облако для себя. Им делаешь всё ту же версию и код у двух проектов почти полностью общий (может даже с какими-то общими данными в БД у тебя и у них и немного обрезанными функциями в случае юзеров, чтоб они тебе конкурента в вебе не запустили), но у них уже не постгри а интегрированный скулайт или H2 в случае Java. На 10 юзеров (сколько там в семье людей может быть) его с головой хватит. А на 10 000 000 уже конечно не хватит, они его положат на лопатки.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от masa

Проекты, где переходили на на другу СУБД я видел, но это происходило спустя 5-10-15 лет разработки

А я видел проекты, которые никуда не переходили, а просто умеют поддерживать несколько разных СУБД в зависимости от того, как админ настроил. Пример – opensimulator.

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

hobbit ★★★★★
()
Ответ на: комментарий от peregrine

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

ya-betmen ★★★★★
()
Ответ на: комментарий от UriZzz

Является частным случаем варианта «не работаю с БД», кажется, последний в списке.

Работающие с БД обычно в курсе, что такое первичный ключ :)

hobbit ★★★★★
()

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

splinter ★★★★★
()
Ответ на: комментарий от peregrine

Ну например берут Sqlite какой-то или мускуль, но понимают что если проект взлетит, то надо будет брать постгри или оракл

Что за каша у тебя в голове?

sqlite - да, на большие проекты не рассчитан, но для баз до 1гб наверно норм

mysql (теперь переименовано в mariadb) - уже полноценная база, и не надо изображать тут всякую чушь, используется в куче больших проектов

postgres - примерно то же самое что mysql по возможностям, хотя и сделано, кажется, по-аккуратнее, но принципиальных отличий нет

oracle - проприетарная штука, никто в здравом уме не будет её ставить

firkax ★★★★★
()
Ответ на: комментарий от firkax

mysql (теперь переименовано в mariadb)

Нет, категорически неверно. Mariadb - форк MySQL, который ещё хоть как-то шевелится, в отличие от MySQL. MySQL после покупки ораклом почти не развивается, т.к. наивно думать, что Oracle стал бы сам себе выращивать бесплатного конкурента.

postgres - примерно то же самое что mysql по возможностям, хотя и сделано, кажется, по-аккуратнее, но принципиальных отличий нет

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

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

Нет, категорически неверно. Mariadb - форк MySQL,

Юридически - да. На самом же деле разработка (вместе с авторами) переехала под название mariadb, так что это следует считать переименованием. Ну, старое название купил оракл и они себе сделали новое.

(но не во всех) умеет значительно больше, чем MySQL

Где там может быть «значительно» то?

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.