Помогите с проверкой уникальности.

alina_b

Новичок
Помогите с проверкой уникальности.

PHP:
function unikal($row,$table, $var)
 {
  $query = mysql_query ( "SELECT `" . mysql_real_escape_string ( $row ) . "` FROM 
`" . mysql_real_escape_string ( $table ) . "` WHERE 
`" . mysql_real_escape_string ( $row ) . "` = '" . mysql_real_escape_string ( $var ) . "'" );
  if ( mysql_num_rows ( $query ) == 0 )
  {
   return TRUE;
  }
  else {
   return FALSE;
  }
 }
С етои функции проверяю когда добавляю --> есть ли такои код, но при правке етих данных - получается так
что проверяет другие записи и сам себя .
Вопросик такой-как сделать чтобы проверялись другие а не етот которыи редактирируется
Таблица:
id - autoincrement.
kod - int.
 

freeek

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

alina_b

Новичок
Но надо произвести проверку есть ли такои код или название раньше чем делать insert..update.... если делать например название уникальным--проверяю и только если название уникальное -разрешаетсья submit.С добавлением всё нормально.. но когда правка данных - тогда проблемы..
 

dimagolov

Новичок
fixxxer, выявил один неприятный нюанс insert on duplicate key update. если есть и unique key и autoincrement, то autoincrement в таблице будет увеличиваться даже при update
 

Splurov

Новичок
dimagolov, как воспроизвести?
Код:
CREATE TABLE upd (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  unique_number INT(10) UNSIGNED NOT NULL DEFAULT 0,
  UNIQUE unique_number(unique_number),
  some_string VARCHAR(255) NULL DEFAULT NULL
) ENGINE=MyISAM;
INSERT INTO upd SET unique_number=10, some_string=10;
INSERT INTO upd SET unique_number=10, some_string=11 ON DUPLICATE KEY UPDATE some_string=13;
INSERT INTO upd SET unique_number=10, some_string=12 ON DUPLICATE KEY UPDATE some_string=14;
Как и ожидалось — в таблице одна строчка c id=1, unique_number=10, some_string=14.
 

dimagolov

Новичок
Splurov, вообще-то смотреть нужно было в SHOW CREATE TABLE upd. но сейчас попробовал, и таки да, вроде не увеличивается. значит дело было в чем-то другом, а не в ON DUPLICATE KEY UPDATE там, где я заметил увеличение AUTO_INCREMENT, посмотрю внимательнее.
 

Gas

может по одной?
При replace меняется ID если его явно не задавать:

Код:
REPLACE upd(id, unique_number, some_string) values(null, 10,15);
 

dimagolov

Новичок
Gas, а чего ты ожидал? id у нас NOT NULL, ты же подсовываешь null, а раз AUTO_INCREMENT то происходит подстановка его значения из AUTO_INCREMENT с увеличением последнего.

п.с. похоже, что у меня нечто подобное происходило, но при ON DUPLICATE KEY UPDATE
 

dimagolov

Новичок
значит у меня где-то бажная версия стоит
Splurov, спасибо, за линк
 

fixxxer

К.О.
Партнер клуба
Это в 5.1 изменился режим блокировки автоинкремента.

http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html

innodb_autoinc_lock_mode = 1 (“consecutive” lock mode)

This is the default lock mode. In this mode, “bulk inserts” use the special AUTO-INC table-level lock and hold it until the end of the statement. This applies to all INSERT ... SELECT, REPLACE ... SELECT, and LOAD DATA statements. Only one statement holding the AUTO-INC lock can execute at a time.

With this lock mode, “simple inserts” (only) use a new locking model where a light-weight mutex is used during the allocation of auto-increment values, and no table-level AUTO-INC lock is used, unless an AUTO-INC lock is held by another transaction. If another transaction does hold an AUTO-INC lock, a “simple insert” waits for the AUTO-INC lock, as if it too were a “bulk insert.”

This lock mode ensures that, in the presence of INSERT statements where the number of rows is not known in advance (and where auto-increment numbers are assigned as the statement progresses), all auto-increment values assigned by any “INSERT-like” statement are consecutive, and operations are safe for statement-based replication.

Simply put, the important impact of this lock mode is significantly better scalability. This mode is safe for use with statement-based replication. Further, as with “traditional” lock mode, auto-increment numbers assigned by any given statement are consecutive. In this mode, there is no change in semantics compared to “traditional” mode for any statement that uses auto-increment, with one important exception.

The exception is for “mixed-mode inserts”, where the user provides explicit values for an AUTO_INCREMENT column for some, but not all, rows in a multiple-row “simple insert.” For such inserts, InnoDB will allocate more auto-increment values than the number of rows to be inserted. However, all values automatically assigned are consecutively generated (and thus higher than) the auto-increment value generated by the most recently executed previous statement. “Excess” numbers are lost.

A similar situation exists if you use INSERT ... ON DUPLICATE KEY UPDATE. This statement is also classified as a “mixed-mode insert” since an auto-increment value is not necessarily generated for each row. Because InnoDB allocates the auto-increment value before the insert is actually attempted, it cannot know whether an inserted value will be a duplicate of an existing value and thus cannot know whether the auto-increment value it generates will be used for a new row. Therefore, if you are using statement-based replication, you must either avoid INSERT ... ON DUPLICATE KEY UPDATE or use innodb_autoinc_lock_mode = 0 (“traditional” lock mode).
лично я для типичных случаев проблемы не вижу, бигинта хватит на всю жизнь и одного, и половинки ) если же действительно таких много, можно либо переписать запрос, либо изменить режим блокировки на старый.
 
Сверху