SQL

Вопрос по SQL - уникальное поле ID для трёх таблиц (нельзя вставить значения в одну, если оно есть в другой таблице).

Здравствуйте, товарищи! Помогите мне написать такой SQL код, чтобы при записи в БД, пользователь выбирал ID и в зависимости от некоторого условия (неважно какого - это я уже продумал) значение вписывалось то в одну таблицу, то в другую, а то и в третью. НО! Важно, чтобы для всех этих трёх таблиц не было повторов значений столбца ID, то есть оно уникально для всех трёх таблиц. Делаю на PhpMyAdmin с целью создания тестовой системы (вопросы могут быть с флажками, радио или письменные). Заранее благадарю Вас!
Vladimir Vdovicenko
Vladimir Vdovicenko
1 082
В некоторых СУБД есть специальный объект - sequence или генератор, для создания уникальных значений. В MySQL такого объекта нет, но есть замена:
https://stackoverflow.com/questions/26578313/how-do-i-create-a-sequence-in-mysql
Но при использовании sequence (или аналога) пользователь не выбирает ID самостоятельно. Если пользователь сам выбирает ID, необходимо проверить, что такого ID нет во всех таблицах. Тут есть проблема: два пользователя могут одновременно выбрать один ID.
Андрей Синяков
Андрей Синяков
58 065
Лучший ответ
Vladimir Vdovicenko Ой сложно, я думаю легче будет сделать как в дополнении к этому вопросу :)
Глеб Пономарёв Дык у дего ID выбирает пользователь, а не из глобального объекта берется, поэтому принципиально не получится.
Vladimir Vdovicenko Есть радикально "тупой" вариант - слить эти таблицы в одну с 60 полями, но это - безумие, как я думаю. Вопос: так на практике кто-нибудь делал? Не отразиться ли это на скорость работы?
Не выйдет так (из-за отсутствия в такой модели вменяемого глобального объекта и возможности существования параллельных транзакций), придумай что-то другое.
Глеб Пономарёв
Глеб Пономарёв
99 975
Vladimir Vdovicenko Идея есть - ловить на сервере все поля `id` у двух таблиц и на основе их делать запос уже в третью, но не хотелось бы прибегать к такому варианту...
Сама идея что пользователь ВЫБИРАЕТ некое значение которое используется сугубо в технических целях (аутоинкрементное связующее поле) выглядит если не полным бредом то как минимум чем-то мега костыльным.
Храните идентификатор который выбирает пользователь отдельно, а идентификаторы назначайте по своим правилам.
Vladimir Vdovicenko Да, на это уже обратил внимание Дед Мазай в этой ветке - делать 4 таблицу со значениями пользователей, а у другх таблиц конечно `id` с auto_increment
Так в чем проблема? Садись и пиши))
Чтобы решить эту задачу хотя-бы кое-как и криво, начни с того, что разбей на более мелкие и простые подзадачи. Не нужно всё лепить в один запрос, нужно разделить на несколько. И логику желательно реализовать в виде хранимой процедуры на стороне сервера. Первым делом нужно будет запускать подзапросы SELECT MAX(ID) по всем участвующим в хранении данных таблицам. Например, из 3-х запросов SELECT MAX(ID) получаешь наибольшее значение, увеличиваешь его на 1 и находишь новое значение ID в одной из таблиц. Сохраняешь по своим условиям очередную запись в выбранную таблицу. Следующую запись после выборки нового (MAX(ID)+1) из 3-х таблиц сохраняешь в другую таблицу (или в эту же, как условие выпадет). Элементарно же. Нечего тут думать принципами ООП. Только поля ID должны быть просто целые числовые не автоинкрементные.
ОЕ
Ольга Елина
37 945
Vladimir Vdovicenko Да, это как вариант, но "эталонный" ответ - это связь всех трёх таблиц по одному уникальному полю :), а так, да, ваш пример может подойти, но вот не хочется перегружать сервер запросами.
В чем проблема то?
Сделайте один столбец id с инкрементом.
В каждой таблице сделайте отдельный столбец для глобального уникального global_id
Генерируйте его по формуле:

Для первой таблицы: global_id = id * 3
Для второй таблицы: global_id = (id * 3) + 1
Для третьей таблицы: global_id = (id * 3) + 2

У вас никогда не будет одинаковых значений в global_id

Это костыль, но он рабочий. Чистейшая математика

Технически можно даже не создавать столбец global_id, а просто при считывании с этой таблицы строк автоматически переводить id в global_id по формуле

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

Более того, вы даже сможете по значению global_id определять из какой таблицы взято значение

-----
Хотя на кой я это пишу.. Там уже какие-то триггеры, доп. таблицы обсуждаются.. Куча ненужных запросов в БД..
-----
Ох, а что будет, если за id принять время создания строки в линуксоидном формате...
Или поменять стартовое и инкрементное значение..

Ладно, пойду пить кофе
ОМ
Олег Мантур
10 661
Vladimir Vdovicenko Костыли - не для меня. Этот проект я надеюсь сделать без всяких пРиКоЛоВ :)