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