2015-01-17 5 views
0

У меня есть эти таблицы:Одновременные Key Value Таблица

CO_KEYVALUE:

co_keyvalueid int 
co_keyid int 
value text 

CO_KEY:

co_keyid int 
keyname varchar(128) 

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

Например:

Клиент 1 вставок ("Name", "Клиент 1")

В то же время, клиент 2 вставок ("Название", "Клиент 1")

Function Put(Name, Value) { 
    Id = SELECT co_keyid FROM co_key WHERE co_keyname = :Name 

    If(!Id) { 
     // Autoincrement 
     Id = INSERT INTO co_key (NULL, :Name) 
    } 

    INSERT INTO co_keyvalue (NULL, :id, :Value) 
} 

Я знаю, что могу заблокировать весь стол, но есть ли другой способ?

+0

В какой базе данных? Если вы определяете их как UNIQUE, DB должен справиться с этим. – SriniV

ответ

1

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

Итак, решение вашей проблемы - пара уникальных ограничений/индексов: co_key(keyname) и co_keyvalue(co_keyid, value). После того, как вы их найдете, вам нужно будет проверить наличие ошибок в коде, которые генерируются неправильными данными.

+0

Правильно ... Поэтому я должен проверить наличие ошибки: INSERT INTO co_key (NULL,: Name), и если он выбрасывает «уникальное нарушение», я должен снова выполнить «SELECT» в таблице? – user3558040

+0

@ пользователь3558040. , , Я, вероятно, сделаю это в другом порядке. Ищите идентификатор, и если он не существует, вставьте его, а затем используйте 'last_insert_id()'. –

+0

Это не то, что я делаю? – user3558040