ID++ | |
---|---|
shumik73 Автор Сообщений: 554 Откуда: Алматы Дата регистрации: 10.05.2006 |
Добрый день
Вопрос добавления новой записи в MSSQL тема не новая, можно сказать детская - но все же хочу еще раз ее затронуть Может на форуме уже тема разобрана - и ограничится ссылкой. Но пока так быстро не нашёл Стандартно 1) Есть таблица с данными TABLE1 2) В таблице есть ключевое поле ID int 3) Чтобы гарантировать уникальность и скорость "Создаётся первичный ключ" PRIMATY KEY 4) При добавление вычисляется максимальное значение SELECT MAX(ID) as Count FROM TABLE1 и значение присваивается переменной nRow 5) Далее команда добавления - тут 2 варианта решения вариант №1 - сразу добавить все значения в одной команде INSERT INTO (ID,.....) VALUES (<nrow+1>,...) вариант №2 - добавляется с строка с новым ID, потом прописываются остальные значения INSERT INTO (ID) VALUES (<nrow+1>) UPDATE TABLE SET X=.., Y=.. WHERE ID=<nrow+1> Работа с документами (записями) привела к созданию двух универсальных функций (выбор ключа и обновление по ключу): А далее для обоих режимов UPDATE TABLE SET X=.., Y=.. WHERE ID=<...> Но у Варианта №2 есть и недостатки 1) При вычисление max(nrow) каким-то образов может вернуть 0, а такой записи быть не должно 2) Строка с ID добавится а в остальных полях NULL. А при обновление может возникнуть ошибка. После этого в таблице остаются битые строчки и в таблице перестают работать DymanicBackColor Поделитесь как более изящно организовать процесс добавления и обновление записей ? Возможно в команду обновление сразу включить вычисление нового ключа? Есть стандартные средства MSSQL
Но поля IDENTITY не использовал, так как их нужно создавать изначально при создание таблицы и на сколько помню их сложно редактировать ![]() |
Re: ID++ | |
---|---|
alex; Сообщений: 3392 Откуда: Москва Дата регистрации: 23.11.2004 |
Мтк, поля IDENTITY можно добавлять и после создания таблицы.
Редактировать поля IDENTITY нельзя. ![]() |
Re: ID++ | |
---|---|
of63 Сообщений: 25996 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
Поделитесь как более изящно организовать процесс добавления и обновление записей ?
Возможно в команду обновление сразу включить вычисление нового ключа? "Изящности" нет. Добавляй/изменяй записи, и "сам поймешь" ![]() |
Re: ID++ | |
---|---|
sphinx Сообщений: 31891 Откуда: Каменск-Уральски Дата регистрации: 22.11.2006 |
Я видел решение, что значения всех последних ключей во всех таблицах хранится в специальной табличке.
Плюсы: - не надо вычислять последнее (максимальное) значение ключа, берез из таблицы + 1. Минусы: - есть у меня стойкое мнение, что рано или поздно произойдет рассогласование и тогда упадет весь проект. Поэтому предпочитаю вычислять на лету. А в редкоиспользуемых справочниках вообще стоит автоинкремент. ------------------ "Veni, vidi, vici!"(с) ![]() |
Re: ID++ | |
---|---|
Дмитрий Петров Сообщений: 3086 Откуда: Пермь Дата регистрации: 09.07.2001 |
В предыдущем проекте на Оракле много где на сиквенсы id -шники были завязны. Сейчас в postgresql тоже встречается такое.
![]() |
Re: ID++ | |
---|---|
PaulWist Сообщений: 14740 Дата регистрации: 01.04.2004 |
Для начала КАК ПРОЧИТАТЬ ЗНАЧЕНИЕ ПОЛЯ СО СВОЙСТВОМ IDENTITY
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) ![]() |
Re: ID++ | |
---|---|
Каратаев Сообщений: 4048 Откуда: Алматы Дата регистрации: 04.12.2001 |
А вот действительно, автоинкремент почему бы не использовать? ------------------ Никогда не бывает настолько плохо, чтобы не могло быть еще хуже. ![]() |
Re: ID++ | |
---|---|
sphinx Сообщений: 31891 Откуда: Каменск-Уральски Дата регистрации: 22.11.2006 |
Саш, это уже обсуждалось неоднократно. Владимир Максимов писал, что-то я, безусловно, подзабыл... Поэтому для журналов вычисляю, а для справочников можно и автоинкремент. Есть справочники, которые меняются условно. Ну какие там проблемы могут быть?
------------------ "Veni, vidi, vici!"(с) ![]() |
Re: ID++ | |
---|---|
PaulWist Сообщений: 14740 Дата регистрации: 01.04.2004 |
Какой сокральный смысл в хинтах holdlock tablelockx
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) ![]() |
Re: ID++ | |
---|---|
alex; Сообщений: 3392 Откуда: Москва Дата регистрации: 23.11.2004 |
Этот код был сгенерирован в SSMS. Думаю, это полная блокировка таблицы перед удалением. Так как я убрал begin tran и commit, то смысл теряется. Вы, правы. ![]() |
Re: ID++ | |
---|---|
AndyNigmatec Сообщений: 1675 Откуда: Волгоград Дата регистрации: 28.06.2015 |
я в firebird для целей получения уникального id сиквенсы (генератор) и использовал - они (сиквенсы) там незавимые и дубликатов не происходит ... может неверное решение, но меня не подводило еще не разу.
![]() |
Re: ID++ | |
---|---|
sphinx Сообщений: 31891 Откуда: Каменск-Уральски Дата регистрации: 22.11.2006 |
Мы с Сашей Каратаевым больше про фокс. В ПГ сиквенсы. И автоинкременты. Уж не знаю, все ли по фен-шую, или частично...
![]() ------------------ "Veni, vidi, vici!"(с) ![]() |
Re: ID++ | |
---|---|
PaulWist Сообщений: 14740 Дата регистрации: 01.04.2004 |
При операциях DDL не требуется накладывать боокировки на данные, используются блокировки метаданных модификации схемы.
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) ![]() |
Re: ID++ | |
---|---|
PaulWist Сообщений: 14740 Дата регистрации: 01.04.2004 |
Так делать не надо. Задача разделяется на две. 1. Все манипуляции с данными производятся на клиенте в фоксе (RV/SPT), то есть прежде чем отправить данные на сервер надо знать "следующий" PK, в этом случае надо использовать последовательности/ф-ии (SEQUENCE/NewID(), NEWSEQUENTIALID() ). В этом случае достаточно послать запрос на сервер
2. Манипуляция данными с помощью ХП, тогда можно использовать п.1, а так же всякие Scope_Identity(), OUTPUT inserted/deleted итп. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) Исправлено 1 раз(а). Последнее : PaulWist, 30.04.24 20:51 ![]() |
Re: ID++ | |
---|---|
Владимир Максимов Сообщений: 14146 Откуда: Москва Дата регистрации: 02.09.2000 |
Начать надо с определений
![]() Primary Key - это поле, по значению которого можно однозначно идентифицировать запись таблицы. А вот чем именно является содержимое этого поля - числом или чем-то еще - совершенно не имеет значения. Это может быть GUID, это может быть некий текст, это может быть число или комбинация всего перечисленного Просто по содержимому этого поля должна быть возможность однозначно идентифицировать запись. Не должно быть дублей. Все остальные свойства Primary Key - вторичны. Да, эти "вторичные" свойства тоже могут быть важны, но если не решается основная задача однозначной идентификации, то от таких вариантов формирования Primary Key стоит отказаться Первый выбор - это выбор между "естественными" и "суррогатными" ключами ЕСТЕССТВЕННЫЕ ИЛИ СУРРОГАТНЫЕ КЛЮЧИ В общем, лучше использовать "суррогатные" ключи ![]() Дальше следует определится с типом данных. GUID Самый простой вариант. Его можно генерировать где угодно и когда угодно. Любой функцией, которая может это делать. В MS SQL это функция NewId(). В рамках любой "самоделки" вполне можно считать, что GUID обеспечивает уникальную идентификацию записи. Недостаток GUID (кроме размера в 16 байт) в его "не читабельности". Сложно запомнить "на глаз". Но, тут вопрос в том, что и 10 цифр в качестве идентификатора тоже не очень-то запомнишь ![]() Цифро-буквенный идентификатор Это что-то вроде номера документа. Исходящий/входящий документ, номер заказа. Т.е., вообще-то, это "естественный" ключ, но формирующийся автоматически. Для таких идентификаторов лучше делать отдельную таблицу с полем-счетчиком и полями с текстом приставок, суффиксов, окончаний. Для генерации нового ключа находим нужную запись в этой таблице, увеличиваем счетчик и формируем новое значение. Тут важно выполнять все это в отдельном соединении, чтобы не подвешивать всю систему, когда разные пользователи добавляют записи в одну таблицу. Т.е. новое значение должно формироваться вне текущей транзакции, что как раз и можно реализовать через отдельное соединение с MS SQL Да, конечно, возможна рассинхронизация, раз счетчик - это отдельная таблица. Но это контролируется уникальным индексом. Будет нарушение уникальности, если счетчик в этой таблице окажется поврежден или не корректен Целое число Ну да. С этого обычно начинают, а не заканчивают ![]() Из простого. Max() - абсолютно запрещенный прием для многопользовательских приложений. Вы практически сразу получите сообщения о попытке создания дублей. Не то, чтобы формирование очередного номера через вычисление максимального значения нельзя было использовать вообще, но в многопользовательских приложениях - это можно делать только как исключение в очень особых таблицах Для решения проблемы в MS SQL есть следующие варианты
2. Объект Sequence 3. Отдельная таблица со счетчиками Собственно, все варианты можно рассматривать именно что как "отдельная таблица". Просто по разному физически реализованные Из "непонятного" тут разве что объект Sequence. Тут только вопрос в версии MS SQL, поскольку этот объект в младших версиях не существовал. Не в курсе, с какой версии MS SQL он появился, так что тут надо смотреть, есть ли он в той версии, с которой работаешь Объект Sequence можно рассматривать именно что как отдельную таблицу со счетчиком к которой организован специфический доступ. Но, может оказаться, что создать собственную таблицу будет более оптимальным решением Для свойства Identity ключевой недостаток в том, что значение формируется только после создания записи. Впрочем, в статье, ссылку на которую привел Паша описано, как можно обойти. Тут надо смотреть по решаемой задаче, подойдет ли такое решение или нет С целыми числами также будут проблемы при репликации (объединении баз данных) приложений. Есть разные варианты решений, но с ограничениями В общем, целое число как Primary Key - это интуитивно понятное, но, как ни странно, самое сложное решение с точки зрения дальнейшего развития приложения. ![]() |
Re: ID++ | |
---|---|
of63 Сообщений: 25996 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
> В общем, целое число как Primary Key - это интуитивно понятное
Владимир, не усложняйте, и не упрощайте. "Интуитивное" - это не причина чего-либо, сами знаете ()() Чекнулся сначала ... Володя, . Очсисторожнее с высказываниями. Хотя, я против тормозов. Спс за всякое при ВФП SQL=ЯП использовании ) () прогерство, и математика, и просто энтузиазм, как были, так и остались движем "") Исправлено 3 раз(а). Последнее : of63, 03.05.24 00:08 ![]() |
© 2000-2025 Fox Club  |