Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Insert c проверкой на уникальность / 19 сообщений из 19, страница 1 из 1
22.10.2015, 00:28
    #39082957
borobos
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Поскольку хорошего решения не нашел решил спросить совета.

Есть postgreSQL 9.4.

Есть некая таблица
Код: sql
1.
Table1(ID serial, Name text)

.

Есть необходимость добавлять записи в эту таблицу с нескольких потоков так, чтоб не возникало повторяющих ID значений.

В MSSQL на сколько знаю это можно реализовать используя MERGE конструкцию, а какое решение посоветуете с постгрес?
...
Рейтинг: 0 / 0
22.10.2015, 01:50
    #39082973
p2.
p2.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
borobosПоскольку хорошего решения не нашелда уж уникальность serial неразрешимая проблема.
borobosВ MSSQL на сколько знаю mssql, насколько знаю, не гарантирует отсутствие нарушения уникальности при конкурентном выполнении без дополнительной блокировки таблицы. Так что ради только инсерта его использовать все равно нет смысла.
...
Рейтинг: 0 / 0
22.10.2015, 01:53
    #39082975
ChA
ChA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
borobosПоскольку хорошего решения не нашел решил спросить совета.

Есть postgreSQL 9.4.

Есть некая таблица
Код: sql
1.
Table1(ID serial, Name text)

.

Есть необходимость добавлять записи в эту таблицу с нескольких потоков так, чтоб не возникало повторяющих ID значений.

В MSSQL на сколько знаю это можно реализовать используя MERGE конструкцию, а какое решение посоветуете с постгрес?При чём здесь MERGE ? Просто поле идентификатора объявляется в MSSQL автоинкрементым
Код: sql
1.
2.
3.
4.
Table1(
ID int identity
, Name text
)

и любая вставка данных с какого-бы то ни было потока получает своё значение. Никаких пересечений в принципе нет и быть не может. В PostgreSQL аналогично, только вместо слова identity указываете serial и получаете ту же самую автоматическую генерацию идентификаторов, которая не зависит от такого с какого потока и каким оператором вы вставляете данные. Или Вы о чем-то другом ?
...
Рейтинг: 0 / 0
22.10.2015, 11:17
    #39083204
borobos
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
ChA,

Извиняюсь, не правильно понял задачу и соответственно спросил.

Задача состоит делать вставку в эту таблицу с нескольких потоков с проверкой на уникальность поля Name.

Другими словами, есть некая таблица:
Код: sql
1.
2.
3.
4.
5.
Table2
(
  ID int, 
  SomeName text
)


нужно сделать что-то типа:
Код: sql
1.
2.
3.
4.
INSERT INTO Table1 (Name)
  SELECT SomeName
  FROM Table2
  WHERE SomeName <> Name



Когда вставка производится в нескольких потоков нужно гарантировать уникальность значений в поле Name.
Вот поэтому я и вспомнил про MSSQL и эго MERGE которым можно сделать груповую вставку с проверкой на наличие дубля.
...
Рейтинг: 0 / 0
22.10.2015, 11:30
    #39083220
p2.
p2.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
borobosВот поэтому я и вспомнил про MSSQL и эго MERGE которым можно сделать груповую вставку с проверкой на наличие дубля.чудак. mssql обеспечиват бездубли за счет блокировки, а не merge. С его подходом к блокировкам, решение получается практически однопоточное. Шаг влево-вправо с послаблением блокировок, бездубли не гарантированы. Если нужно только добавлять строки без апдейта - это insert-select, а уж в селекте можешь проверять что угодно, включая дубли. И обязательно unique-констрейнт. Ну случится ошибка, будешь повторять операцию до посинения.
...
Рейтинг: 0 / 0
22.10.2015, 13:01
    #39083412
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
borobosChA,

Извиняюсь, не правильно понял задачу и соответственно спросил.

Задача состоит делать вставку в эту таблицу с нескольких потоков с проверкой на уникальность поля Name.

Другими словами, есть некая таблица:
Код: sql
1.
2.
3.
4.
5.
Table2
(
  ID int, 
  SomeName text
)


нужно сделать что-то типа:
Код: sql
1.
2.
3.
4.
INSERT INTO Table1 (Name)
  SELECT SomeName
  FROM Table2
  WHERE SomeName <> Name



Когда вставка производится в нескольких потоков нужно гарантировать уникальность значений в поле Name.
Вот поэтому я и вспомнил про MSSQL и эго MERGE которым можно сделать груповую вставку с проверкой на наличие дубля.

2 варианта: before insert триггер тихо убирающий вставку дублей
или сделать uniq index на name и обрабатывать ошибки вставки дубля на уровне приложения (обработка - игнорирование)

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
22.10.2015, 13:26
    #39083469
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Maxim BogukborobosChA,
<>

Задача состоит делать вставку в эту таблицу с нескольких потоков с проверкой на уникальность поля Name.

<>
Когда вставка производится в нескольких потоков нужно гарантировать уникальность значений в поле Name.


2 варианта: before insert триггер тихо убирающий вставку дублей
или сделать uniq index на name и обрабатывать ошибки вставки дубля на уровне приложения (обработка - игнорирование)

--
Maxim Boguk
в before insert тоже придется обрабатывать исключение.
Т.е. вариант в сущности 1.
Но с обработкой исключения "на уровне приложения" -- лучше -- меньше счетчик транзакций накручивается. (на "сабтранзакциях")

зато с триггером -- можно будет батчами вставлять.


вот бы еще имена на длинные целые отобразить -- был бы вариант с адвайзори.всё таки пространство имен для адвайзори -- куцеватенькое
...
Рейтинг: 0 / 0
22.10.2015, 14:36
    #39083632
ChA
ChA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
borobosделать вставку в эту таблицу с нескольких потоков с проверкой на уникальность поля Name.

Другими словами, есть некая таблица:
Код: sql
1.
2.
3.
4.
5.
Table2
(
  ID int, 
  SomeName text
)


нужно сделать что-то типа:
Код: sql
1.
2.
3.
4.
INSERT INTO Table1 (Name)
  SELECT SomeName
  FROM Table2
  WHERE SomeName <> Name



Когда вставка производится в нескольких потоков нужно гарантировать уникальность значений в поле Name.
Вот поэтому я и вспомнил про MSSQL и эго MERGE которым можно сделать груповую вставку с проверкой на наличие дубля.Проще говоря, надо добавлять данные из другой таблицы, кроме тех, которые уже были перенесены ранее ?
...
Рейтинг: 0 / 0
22.10.2015, 14:44
    #39083655
Author the new one
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
qwwq,

А что же, вы не умеете к штыку приравнять перо, тьфу, из строки сделать число? Ну так возьмите md5 от строки, выдерите оттуда сколько надо байт и сделайте из них что надо. Ну или возьмите недокументированную функцию hashtext(text). Но, знаете, тут есть проблема, да и не проблема даже, но проблемка - надо увеличивать max_locks_per_transaction, так что вариант с уникальным индексом мало того, что полезен и, если можно так выразиться, не нетрадиционен, так еще и сервер крутить не надо. Вариант с триггером, конечно, изящен, но тоже, так сказать, смузями пахнет, проще уж

do $code$
begin
insert into tbl(...) values(...);
exception
when unique_violation then null;
end;
$code$

Можно и в функцию обернуть.
...
Рейтинг: 0 / 0
22.10.2015, 14:46
    #39083659
Author the new one
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
ChAborobosделать вставку в эту таблицу с нескольких потоков с проверкой на уникальность поля Name.

Другими словами, есть некая таблица:
Код: sql
1.
2.
3.
4.
5.
Table2
(
  ID int, 
  SomeName text
)


нужно сделать что-то типа:
Код: sql
1.
2.
3.
4.
INSERT INTO Table1 (Name)
  SELECT SomeName
  FROM Table2
  WHERE SomeName <> Name



Когда вставка производится в нескольких потоков нужно гарантировать уникальность значений в поле Name.
Вот поэтому я и вспомнил про MSSQL и эго MERGE которым можно сделать груповую вставку с проверкой на наличие дубля.Проще говоря, надо добавлять данные из другой таблицы, кроме тех, которые уже были перенесены ранее ?
Это все очень хорошо, но многопоточный вариант работать не будет.
...
Рейтинг: 0 / 0
22.10.2015, 15:18
    #39083755
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Author the new oneqwwq,

А что же, вы не умеете к штыку приравнять перо, тьфу, из строки сделать число?
и вы не знаете.
задача -- гарантированно взаимно--однозначно отобразить произвольное (ещё не данное вам в ощущения) подмножество множества строк, о котором известно лишь что оно [будет в любой момент] не слишком велико, на множество бигинтов.

вот это вот гарантированно взаимно--однозначно не очень сочетается с "наперёд неизвестностью".
печалька.

приходится вкручивать лохам байку об гастрономически малой вероятности совпадения.
лох хавает, чо.

миша тюринг вааще по каррент--таймстампу любил транзакции идентифачить -- и ведь до сих пор его работодатель не попёр.

Author the new oneНу так возьмите md5 от строки, выдерите оттуда сколько надо байт и сделайте из них что надо. Ну или возьмите недокументированную функцию hashtext(text). Но, знаете, тут есть проблема, да и не проблема даже, но проблемка - надо увеличивать max_locks_per_transaction, так что вариант с уникальным индексом мало того, что полезен и, если можно так выразиться, не нетрадиционен, так еще и сервер крутить не надо. Вариант с триггером, конечно, изящен, но тоже, так сказать, смузями пахнет, проще уж

do $code$
begin
insert into tbl(...) values(...);
exception
when unique_violation then null;
end;
$code$

Можно и в функцию обернуть.
тут печалька в избыточной накрутке счетчика транзакций. евпочя.
и каждый вальюз надо отделять отдельным exception -- т.к. savepoint у вас на begin-е. к нему и откатимся.
...
Рейтинг: 0 / 0
22.10.2015, 15:22
    #39083763
Author the new one
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
qwwq,

авторгарантированно взаимно--однозначно
Скажите, а зачем?
...
Рейтинг: 0 / 0
22.10.2015, 15:23
    #39083766
Author the new one
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
qwwq,

автори каждый вальюз надо отделять отдельным exception -- т.к. savepoint у вас на begin-е. к нему и откатимся.
И?
...
Рейтинг: 0 / 0
22.10.2015, 15:28
    #39083776
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Author the new oneChAпропущено...
Проще говоря, надо добавлять данные из другой таблицы, кроме тех, которые уже были перенесены ранее ?
Это все очень хорошо, но многопоточный вариант работать не будет.вот если адвайзори брать на задачу (один bigint или 2 int-а на всех -- скажем regproc::int + pg_proc.tableoid::int) -- то многопоточный вариант можно выстроить в очередь на , с момента забора очередным до момента commit вставки им же. и таки будет работать -- " в очередь...". ошибки из за узости пространства адвайзори, разделяемого разными задачами, при этом не приведут к хождению мимо тазика (что не допустимо) а к увеличению ожиданий -- что терпимо, если только нет очень долгоиграющих случайных конкурентов.
...
Рейтинг: 0 / 0
22.10.2015, 15:30
    #39083782
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Author the new oneqwwq,

авторгарантированно взаимно--однозначно
Скажите, а зачем?помедитируйте

я что--то нынче не настроен подавать
...
Рейтинг: 0 / 0
22.10.2015, 15:33
    #39083789
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Author the new oneqwwq,

автори каждый вальюз надо отделять отдельным exception -- т.к. savepoint у вас на begin-е. к нему и откатимся.
И?
и многострочный values у вас откатится целиком, а не киксанёт одной строчкой.

а гонять ф-ю, вызываемую на row -- тот же триггер, с небольшими неудобствами явного вызова.
...
Рейтинг: 0 / 0
22.10.2015, 15:52
    #39083833
Author the new one
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
qwwq,

Помедитировал. По-моему вы себе что-то странное придумали. Судите сами - взяли строку, получили адвайзори блокировку, смотрим, есть ли такая, если есть, то и ладно, если нет, то вставляем спокойно, так как ее никто не добавит, вставили, закоммитились, сняли блокировку. Ну и зачем вам тут "взаимно--однозначно"? Или у вас есть какие-то иные варианты?
...
Рейтинг: 0 / 0
22.10.2015, 16:08
    #39083855
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
Author the new oneqwwq,

Помедитировал. По-моему вы себе что-то странное придумали. Судите сами - взяли строку, получили адвайзори блокировку, смотрим, есть ли такая, если есть, то и ладно, если нет, то вставляем спокойно, так как ее никто не добавит, вставили, закоммитились, сняли блокировку. Ну и зачем вам тут "взаимно--однозначно"? Или у вас есть какие-то иные варианты?а если кто--то уже залочил --- ждём ?
если да -- то вы правы, вероятно.


я--то думал вставлять пакеты, а не строки, и, тогда, пропускать вставку того , что залочено --
INSERT .....
WHERE...try...advisory... xact((f(name))
-- что было бы не верно.

ошибся не расписав.
...
Рейтинг: 0 / 0
22.10.2015, 18:23
    #39084016
borobos
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert c проверкой на уникальность
ChA,

да, верно
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Insert c проверкой на уникальность / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]