Классическая проблема вставки базы данных - PullRequest
1 голос
/ 06 февраля 2009

У меня есть база данных SQL, которую я использую для хранения некоторой информации, и каждая запись имеет уникальный идентификатор, сгенерированный базой данных. Моя программа написана на флэш-памяти и запускается через Интернет, программа работает нормально, она вставляет записи в базу данных и извлекает id последней записи и отображает ее для пользователя. Мой вопрос заключается в том, как мне обработать несколько одновременных записей, потому что Программа будет использоваться несколькими пользователями, и есть вероятность одновременного добавления в базу данных, чтобы я мог идентифицировать правильные уникальные идентификаторы для пользователей

вот код для вставки в базу данных

$query = "INSERT into $tablename (grade,school,country) VALUES ('$datarray[0]','$datarray[1]','$datarray[2]')";
$result = mysql_query($query) 
        or die("no rows selected");

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

$query = "SELECT max(id) from $tablename";
$result = mysql_query($query) 
        or die("no rows selected");
$row = mysql_fetch_array($result); // extracts one row
echo  "id=$row[0]";

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

Ответы [ 11 ]

4 голосов
/ 06 февраля 2009

PHP имеет mysql_insert_id() для возврата

Идентификатор, сгенерированный для AUTO_INCREMENT столбец по предыдущему запросу INSERT на успех, 0, если предыдущий запрос делает не генерировать AUTO_INCREMENT значение, или FALSE, если не было MySQL-соединения установлен.

3 голосов
/ 06 февраля 2009

Большинство баз данных поддерживают ключ UUID / GUID. Создайте его с помощью вашего бэкэнда (или даже ActionScript) и используйте его в базе данных. Это не естественный ключ, но он идеально подходит для уникальности даже в фермах серверов.

2 голосов
/ 06 февраля 2009

Вы можете выполнить вставку и последующие операции выбора в одной транзакции. Вы также можете иметь доступ к объектам в зависимости от вашей базы данных.

1 голос
/ 06 февраля 2009

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

1 голос
/ 06 февраля 2009

Если код вашей базы данных возвращает идентификатор последней вставленной строки, это определенно вызовет проблемы.

Если вы используете сервер SQL, вы можете использовать:

SELECT SCOPE_IDENTITY()

для выбора верного идентификатора. Больше информации в статье MSDN .

Было бы полезно, если бы вы дали больше информации о том, как вы выполняете вставку в базу данных и какую технологию вы используете

0 голосов
/ 06 февраля 2009
insert ....; select last_insert_id()
0 голосов
/ 06 февраля 2009

Во-первых, вы используете PHP и MySQL. Столбцы идентификаторов обычно должны быть определены как:

id int( 4 ) UNSIGNED NOT NULL AUTO_INCREMENT,
-- Constraints
primary key (id)

Использование идентификатора в качестве имени является самодокументированным. 4-байтовое целое число может быть излишним, особенно если оно не подписано, но место дешевое и очень маловероятно, что у вас когда-либо закончатся идентификаторы.

Я также предлагаю по возможности использовать движок InnoDB. Внешние ключи и целостность данных - замечательные вещи.

Ваш сценарий должен выполнять mysql_connect (), и это означает, что каждый пользователь получит свое собственное соединение с базой данных, поскольку сеанс каждого пользователя является отдельным экземпляром этого сценария. После вставки вы можете использовать mysql_insert_id (), как указывал предыдущий автор, чтобы получить идентификатор, сгенерированный для вставки.

0 голосов
/ 06 февраля 2009

Обязательно поместите операторы INSERT и SELECT в отдельный запрос , который вставляет данные и возвращает идентификатор.

Важно НЕ использовать два отдельных запроса для получения идентификатора, поскольку после первой вставки другой пользователь может ( и, в конечном итоге, ) вставить другую запись, прежде чем вы сможете получить идентификатор первый.

Если вы используете отдельные транзакции, вы в конечном итоге будете иметь следующий сценарий:

User1 : Inserts a record (id = 123)
User2 : Inserts a record (id = 124)
User1 : Requests max id (and gets back 124) <---- WRONG ID
User2 : Requests max id (and gets back 124)

Как отмечено в постах выше, точный синтаксис для получения вставленного идентификатора зависит от БД.

0 голосов
/ 06 февраля 2009

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

0 голосов
/ 06 февраля 2009

Это в некоторой степени зависит от используемой вами базы данных.

Например, в SQL Server у вас есть несколько вариантов. Вы можете использовать SCOPE_IDENTITY () для получения последнего значения идентификатора, созданного в текущей области.

EX: SELECT @NEWID = SCOPE_IDENTITY ()

В этой статье приводятся некоторые примеры для SQL Server:

http://databases.aspfaq.com/general/how-do-i-get-the-identity/autonumber-value-for-the-row-i-inserted.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...