SERIAL-подобный столбец INT - PullRequest
       16

SERIAL-подобный столбец INT

1 голос
/ 14 августа 2010

У меня есть приложение, в котором в зависимости от типа добавляемой или обновляемой транзакции номер билета может увеличиваться или не увеличиваться. Я не могу использовать тип данных SERIAL для номера заявки, потому что он будет увеличиваться независимо от типа транзакции, поэтому я определил номер заявки как INT. Таким образом, в многопользовательской среде, если пользователь A добавляет или обновляет транзакцию, а пользователь B также делает то же самое, я проверяю тип tran и, если требуется следующий номер билета, тогда

LET ticket = (SELECT MAX(ticket) [WITH ADDLOCK or UPDLOCK?] FROM transactions) + 1

Однако это должно быть сделано именно тогда, когда происходит фиксация строки или возникнут проблемы. Можете ли вы придумать лучший способ сделать это с помощью: Informix, Oracle, MySQL, SQL-Server, 4Js / Genero или других RDBMS? Это один из основных факторов, который определит, в какую СУБД я собираюсь переписать свое приложение.

Ответы [ 3 ]

2 голосов
/ 15 августа 2010

В СУБД Informix столбец SERIAL не изменится после вставки; действительно, вы не можете обновить значение SERIAL вообще. Вы можете вставить новое значение либо с 0 в качестве значения - в этом случае создается новое значение - либо вы можете вставить другое значение. Если другое значение уже существует и существует уникальное ограничение, оно не будет выполнено; если он не существует или если нет уникального ограничения на последовательный столбец, то это будет успешно. Если введенное значение больше наибольшего значения, вставленного ранее, то следующее число, которое будет вставлено, снова будет на одно число больше. Если введенный номер меньше или отрицателен, то следующий номер не влияет.

Таким образом, вы можете выполнить обновление без изменения значения - без проблем. Если вам нужно изменить номер, вам нужно будет удалить и вставить (или вставить и удалить), где вставка имеет ноль. Если вы предпочитаете согласованность и используете транзакции, вы всегда можете удалить, а затем (повторно) вставить строку с тем же номером или с нулем, чтобы вызвать новый номер. Это предполагает, что у вас есть язык программирования, на котором работает SQL; Я не думаю, что вы можете настроить ISQL и Perform, чтобы сделать это автоматически.

Итак, на данный момент я не вижу проблемы в Informix.

С соответствующей версией IDS (все, что поддерживается) вы можете использовать SEQUENCE для управления вставленными значениями. Это основано на синтаксисе и концепции Oracle; DB2 также поддерживает это. Другие СУБД имеют другие эквивалентные (но разные) механизмы для обработки автоматически сгенерированных чисел.

1 голос
/ 16 августа 2010

Это то, для чего были созданы последовательности, и которое поддерживается большинством баз данных (MySQL - единственная, у которой нет последовательностей - хотя на 100% не уверен насчет Informix)

Любой алгоритм, основанный на SELECT MAX (id) Анти-шаблон либо слишком медленный в многопользовательской среде, либо просто не будет работать правильно в многопользовательской среде.

Если вам нужна поддержка MySQL, я бы рекомендовал использовать «родной» тип «автоинкремент» в каждой базе данных (последовательный для PostgreSQL, auto_increment для MySQL, идентификатор для SQL Server, sequence + триггерв Oracle и т. д.) и пусть драйвер возвращает сгенерированное значение идентификатора

В JDBC есть метод getGeneratedKeys (), и я уверен, что другие интерфейсы имеют нечто подобное.

1 голос
/ 14 августа 2010

По вашим тегам сложно определить, какую базу данных вы используете.

Для SQL Server (поскольку он в списке) я предлагаю

ticket_num = (SELECT MAX(ticket_number) FROM transactions with (updlock)) + 1
...