2013-08-10 2 views
0

мне нужно добавить данные в базу данных MySQL так:Вставка лиц с идентификаторами в одном запросе?

Person: pId, nameId, titleId, age

Name: nameId, name

Title: titleId, title

Я не хочу, чтобы иметь какие-либо имена или названия более чем один раз в БД поэтому я не видел решения с LAST_INSERT_ID()

Мой подход выглядит так:

INSERT IGNORE INTO Name(name) VALUES ("Peter"); 
INSERT IGNORE INTO Title(title) VALUES ("Astronaut"); 
INSERT INTO Person(nameId, titleId, age) VALUES ((SELECT nameId FROM Name WHERE name = "Peter"), (SELECT nameId FROM Name WHERE name = "Astronaut"), 33); 

Но я думаю, что это довольно грязный подход !? Если возможно, я хочу добавить нескольких человек с одним запросом и не иметь ничего более одного раза в db. Возможно ли это по-хорошему? Благодаря!

+0

Почему столбец «имя» и «название» не в одном столе? Тогда использование last_insert_id() было бы проще. – KarelG

+0

Возможный дубликат [Design dielema; Если почтовый адрес уже используется, отправьте адрес электронной почты «уже зарегистрированный адрес», но он не может, потому что не может добавить дубликат в таблицу] (http://stackoverflow.com/questions/18154031/design-dielema-if-e mail-address-alread) –

+0

@KarelG, потому что если бы я добавил «Питер», Например, «Астронавт4» я всегда добавлял «Питер» в db. Я хочу хранить «Питер» всего один раз в db и иметь идентификатор как псевдоним для всех остальных peters. Или это не так? Я, хотя вы должны сэкономить как можно больше места ... – user2170547

ответ

0

Вы можете поместить заголовок и имя в виде двух столбцов вашей таблицы, а затем:

  • установить один UNIQUE индекс на каждую колонку, если вы не "т хочет иметь два названия или два названия идентичного в БД
  • или установить UNIQUE индекс на (title,name), если вы не хотите иметь две записи, имеющие как же имя и такое же название.

Если вы действительно хотите иметь отдельные таблицы, вы могли бы сделать, как Вы предложили в вашем посте, но оборачивать все операторы вставки в виде TRANSACTION, чтобы откат, если вы обнаружили копию где-то.

См. Design dilemma: If e-mail address already used, send e-mail "e-mail address already registered", but can't because can't add duplicate to table, которые выглядят как та же проблема, но имеют имя & адрес электронной почты вместо имени &.

START TRANSACTION; 
INSERT INTO title(value) VALUES ("Prof."); 
SELECT LAST_INSERT_ID() INTO @title_id; 
    -- Instead of using user-defined variable, 
    -- you should be able to use the last_insert_id 
    -- equivalent from the host language MySQL driver. 
INSERT INTO username(value) VALUES ("Sylvain"); 
SELECT LAST_INSERT_ID() INTO @username_id; 
    -- Instead of using user-defined variable, 
    -- you should be able to use the last_insert_id 
    -- equivalent from the host language MySQL driver. 

INSERT INTO account(username_id, email_id) VALUES (@username_id,@title_id); 
COMMIT; 

См LAST_INSERT_ID()


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

+0

Я прочитал ваш связанный пост, но я не мог понять, могу ли/как я могу предотвратить подзапрос в последнем вставном запросе с этим? То, что я просто хотел бы сделать, это этот запрос: INSERT INTO Person (nameId, titleId, age) VALUES («Питер», «Космонавт», 33), но с заменой строк связанными идентификаторами. Если для имени нет идентификатора, он должен храниться в других таблицах раньше. – user2170547

+0

@ user2170547 Я отредактировал свой ответ, чтобы показать вам, как это сделать в SQL-only. Основная идея состоит в том, что, поскольку у вас будет две вставки, вы сможете использовать 'last_insert_id()' после каждого 'INSERT', чтобы получить идентификатор каждой записи (при условии, что в столбцах' auto_increment'). Здесь я использую пользовательскую переменную MySQL. В реальном мире вы, вероятно, будете использовать простые переменные с вашего языка хоста. –

+0

Спасибо! Теперь я понимаю! знак равно – user2170547

Смежные вопросы