|
|
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Имеется таблица [Operation], в которой на данный момент 985+ млн. записей. В таблице есть первичный ключ – bigint identity. Он также является внешним, для 6 таблиц связанных с [Operation]. В таблице [Operation] есть 4 поля определяющие уникальность (код подразделения – int, код офиса – int, дата – date, номер операции в течение дня – int). Есть задача: создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся. Сама задача трудностей не вызывает, предполагается создать поле numeric(28,0), для которого внешние приложение будет формировать ключ из полей определяющих уникальность, например так: PPPPOOOOOYYYYMMDDNNN, Где: PPPP – код подразделения, значения всегда положительные, максимальное значение 9999, фактически значений на данный момент 4, ранее было 47; OOOOO – код офиса, значения всегда положительные, максимальное значение 99999, фактически офисов 1500 штук; YYYY – номер года; MM – номер месяца; DD – номер дня; NNN – номер операции в течение дня, значения всегда положительные, первая операция в дне начинается с 1, количество операций зависит от офиса, и может достигать 2 млн. СУБД Microsoft SQL Server 2012 – 11.0.2218.0 (X64) Enterprise (Build 7601: Service Pack 1). Вопрос № 1: в какой последовательности лучше расположить PPPP, OOOOO, YYYY, MM, DD, NNN? Вопрос № 2: возможно есть альтернативное решение? ЗюЫю Все затевается ради того, чтобы обеспечить BulkInsert из внешнего приложения, и исключить вставку записи с последующим запросом значения ключа, чтобы обеспечить наличие внешнего ключа для вставки данных в связанные таблицы. Благодарю за помощь. Модератор: Тема перенесена из форума "Microsoft SQL Server". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2014, 14:39 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Вопрос № 1: в какой последовательности лучше расположить PPPP, OOOOO, YYYY, MM, DD, NNN? Зависит от того, в какой последовательности Вы грузите данные. Общая рекомендация - максимально стараться сделать ключ монотонно возрастающим при операциях загрузки. __TT__TT__Вопрос № 2: возможно есть альтернативное решение? Есть - сделать нормальный Unique constraint на эти 4 поля, сгенеренный ключ для вставки в дочерние таблицы получать соединением по 4ем полям. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2014, 15:27 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Кот Матроскин, извините, уточню, я правильно понял - нужно использовать естественные ключи? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.04.2014, 17:44 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Имеется таблица [Operation], в которой на данный момент 985+ млн. записей. В таблице есть первичный ключ – bigint identity. Он также является внешним, для 6 таблиц связанных с [Operation]. В таблице [Operation] есть 4 поля определяющие уникальность (код подразделения – int, код офиса – int, дата – date, номер операции в течение дня – int). Есть задача: создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся. Сама задача трудностей не вызывает, предполагается создать поле numeric(28,0), для которого внешние приложение будет формировать ключ из полей определяющих уникальность, например так: PPPPOOOOOYYYYMMDDNNN, Где: PPPP – код подразделения, значения всегда положительные, максимальное значение 9999, фактически значений на данный момент 4, ранее было 47; OOOOO – код офиса, значения всегда положительные, максимальное значение 99999, фактически офисов 1500 штук; YYYY – номер года; MM – номер месяца; DD – номер дня; NNN – номер операции в течение дня, значения всегда положительные, первая операция в дне начинается с 1, количество операций зависит от офиса, и может достигать 2 млн. СУБД Microsoft SQL Server 2012 – 11.0.2218.0 (X64) Enterprise (Build 7601: Service Pack 1). Вопрос № 1: в какой последовательности лучше расположить PPPP, OOOOO, YYYY, MM, DD, NNN? Вопрос № 2: возможно есть альтернативное решение? ЗюЫю Все затевается ради того, чтобы обеспечить BulkInsert из внешнего приложения, и исключить вставку записи с последующим запросом значения ключа, чтобы обеспечить наличие внешнего ключа для вставки данных в связанные таблицы. Т.е., фактически всё сводится к тому, чтобы первичный ключ генерировать во внешнем приложении. Самый простой способ, использовать GUID, генерируемый в приложении, можно даже последовательный, хотя это некритично, если не собираетесь по нему делать кластерный индекс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 08:33 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, На случай, если вы не в курсе, внешний ключ может ссылаться на более чем 1 поле таблицы. Конкретно в MSSQL - до 16 включительно. Насколько я понимаю, у вас уже есть натуральный ключ из 4 полей в Operations; ну так переведите форейны на него, вместо идентити. Понятно, что джойны начнут выглядеть несколько устрашающе, но с точки зрения сиквела разницы будет немного. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 08:45 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, Есть задача: создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся. Очень зря. Создать можно другой ключ, альтернативный. Уникальный, если надо. Но заменять им первичный — это лишнее, и неправильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 11:27 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, Сама задача трудностей не вызывает, предполагается создать поле numeric(28,0), для которого внешние приложение будет формировать ключ из полей определяющих уникальность, например так: PPPPOOOOOYYYYMMDDNNN, Это — вообще идиотизм, граничащий с саботажем. Не говоря уже о нарушении 1НФ. Чем составной ключь не устраивает? Он ничуть не хуже , даже лучше . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 11:31 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, Вопрос № 1: в какой последовательности лучше расположить PPPP, OOOOO, YYYY, MM, DD, NNN? Ещё раз, вся идея — идиотизм. В каком порядке поля внутри атомарного поля складывать — абсолютно все равно, потому что поле атомарно. Ты не сможешь использовать куски поля по отдельности. Вопрос № 2: возможно есть альтернативное решение? Да. Не страдать хреновней, создать составной уникальный индекс из этих полей, если надо. PK оставить в покое. ЗюЫю Все затевается ради того, чтобы обеспечить BulkInsert из внешнего приложения, и исключить вставку записи с последующим запросом значения ключа, чтобы обеспечить наличие внешнего ключа для вставки данных в связанные таблицы. Это все можно делать по другому. Bulk можно вставлять в отдельную таблицу, затем переливать в главную. Сгенерированный ключь можно получать тем же запросом, что и вставка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 11:41 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Кот Матроскин, извините, уточню, я правильно понял - нужно использовать естественные ключи? НЕ нужно использовать естественные ключи. Вот так-- правильно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.04.2014, 15:25 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
MasterZivЧем составной ключь не устраивает? Составной ключ устраивает только теоретиков, никогда не пытавшихся всерьёз поработать с ним на практике. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2014, 19:36 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Есть задача: создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся. Если бы эту задачу принесли мне, я бы очень упорно ругался на тему "это неправильная задача и делать надо совсем иначе". __TT__TT__ЗюЫю Все затевается ради того, чтобы обеспечить BulkInsert из внешнего приложения, и исключить вставку записи с последующим запросом значения ключа, Для этого нужно, чтобы внешнее приложение само генерило значение ПК, для этого совершенно не обязательно путаться с естественными ключами и пытаться всунуть два миллиона значений в маску NNN. Как именно генерить - многие пользуются гуидами, если это по какой-то причине нежелательно, то никто не мешает реализовать счётчик самому или воспользоваться функционалом базы, например, сделать в левой табличке поле INCREMENT(1,1000000) // сделали одну вставку - имеем миллион доступных нам id. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2014, 19:46 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Ну вставлю и свои пять. __TT__TT__... создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся С точки зрения теории (тут уже правильно говорили) проблем нет. Но вот на практике за подобное нада пальцы в двери. __TT__TT__Все затевается ради того, чтобы обеспечить BulkInsert из внешнего приложения, и исключить вставку записи с последующим запросом значения ключа, чтобы обеспечить наличие внешнего ключа для вставки данных в связанные таблицы. Т.е. внешнее приложение будет инсертить в вашу БД? Ну дык и пусть инсертит. Вы PK заполняйте автоматом, а внешнее приложение пусть инсертит без PK (оно у вас автоматом на 1 будет увеличиваться на каждом инсерте). Если проблема с заполнением FK в связанных таблицах то выкладывайте схему и рассказывайте в чем именно проблема. Ну а мы расскажем что это совсем непроблема, и подскажем куда копать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2014, 21:02 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
softwarerMasterZivЧем составной ключь не устраивает? Составной ключ устраивает только теоретиков, никогда не пытавшихся всерьёз поработать с ним на практике. Че, все уже сказал? Или ещё что осталось умного? Топик может тогда прочтешь, иногда полезно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2014, 22:12 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Злой Бобр, Давайте попробую внести ясность в задачу. Наверное мой косяк, что сразу поленился расписать все детали. И так, есть текстовые файлы, которые экспортируются из внешней системы. Описание типов и сути полей взято из документации к системе которая эти файлы и генерит. На основнии описания созданы 6 таблиц. Одна из них [Operation], остальные таблицы связаны с ней по FK. В таблице [Operation] есть 4 поля определяющие уникальность (код подразделения – int, код офиса – int, дата – date, номер операции в течение дня – int), на них есть Nonclustered unique contraint, еще в таблице есть первичный ключ - bigint identity. Внешнее приложение разбирает файлы и вставляет записи в таблицы. Проблема в том, что PK генерится в БД и чтобы его получить нужно сначала вставить запись, а потом запросить сгенеренный ID. В итоге получаются дерганье туда-сюда и весь импорт длится целую ночь. Хочется перевести приложение на использование BulkInsert. Поэтому возник вопрос, как генерить ID, т.е. вместо Identity, как вариант было предложено в приложении генерить ID на основании уникальных полей. Сами уникальные поля так и оставить, а у PK убрать identity. Переходить на составной ключ не хотелось из-за необходимости менять джойны, ну и вообще писать лишнее. В общем в идеале нужно оставить все тот же bigint в качестве ПК, а приложение перевести на использование BulkInsert. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 13:38 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Злой Бобр, Давайте попробую внести ясность в задачу. Наверное мой косяк, что сразу поленился расписать все детали. И так, есть текстовые файлы, которые экспортируются из внешней системы. Описание типов и сути полей взято из документации к системе которая эти файлы и генерит. На основнии описания созданы 6 таблиц. Одна из них [Operation], остальные таблицы связаны с ней по FK. В таблице [Operation] есть 4 поля определяющие уникальность (код подразделения – int, код офиса – int, дата – date, номер операции в течение дня – int), на них есть Nonclustered unique contraint, еще в таблице есть первичный ключ - bigint identity. Внешнее приложение разбирает файлы и вставляет записи в таблицы. Проблема в том, что PK генерится в БД и чтобы его получить нужно сначала вставить запись, а потом запросить сгенеренный ID. В итоге получаются дерганье туда-сюда и весь импорт длится целую ночь. Хочется перевести приложение на использование BulkInsert. Поэтому возник вопрос, как генерить ID, т.е. вместо Identity, как вариант было предложено в приложении генерить ID на основании уникальных полей. Сами уникальные поля так и оставить, а у PK убрать identity. Переходить на составной ключ не хотелось из-за необходимости менять джойны, ну и вообще писать лишнее. В общем в идеале нужно оставить все тот же bigint в качестве ПК, а приложение перевести на использование BulkInsert. Как в файлах связаны сущности, попадающие в Operation и дочерние таблицы? Эти сущности тоже раскиданы по разным файлам или соединены в одном? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 13:42 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Кот Матроскин, Файл один, данные в нем идут подряд. Каждая операция начинается с определенного признака, допустим с цифры 1, дальше до конца строки идут данные, разделенные | В следующей строке могут быть сущности относящиеся к операции, которые будут иметь свой признак, например 2, 3, 4, 5, 6, либо новая операция, которая опять же будет начинаться с 1| выглядить примерно так 1|20.01.2014|1|5|1|238.0 2|5|7|3 3|Сквозная система|3.0 1|20.01.2014|1|5|2|33.44 3|Подсистема ...|777 Приложение делит строку по символам | и анализирует первый элемент, на его основании делается вывод куда вставлять данные. В общем-то логика не сложная. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 13:57 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Поэтому возник вопрос, как генерить ID, т.е. вместо Identity, как вариант было предложено в приложении генерить ID на основании уникальных полей. Сами уникальные поля так и оставить, а у PK убрать identity. Ну вроде так и понимали. Генерить на основе уникальных полей в принципе можно, но при этом вы влетаете в две стандартные неприятности: во-первых, размер получающегося поля, а во-вторых, в "пришли кривые неуникальные данные, которые как-то таки надо загрузить". Раз внешнее приложение разбирает и вставляет, мне кажется, ну совершенно никто не мешает ему использовать собственный счётчик, стартуя ну хотя бы с select max(id) - приложение-то почти наверняка будет работать в единственном экземпляре, коллизий не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 14:20 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, Я бы залил файл целиком BULK-ом в буферную таблицу Код: sql 1. 2. 3. 4. 5. где в поле OperationID (при помощи Sequence) проставил бы, какая сущность относится к какой операции Потом делал бы вставки рабочие таблицы в духе Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 14:36 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__, Лично я вижу только 2 варианта: - отдать генерацию ид приложению (я б на такое непошел по понятным причинам, хотя если это чисто справочные или стат данные которые невлияют на рабочий процесс то наверное обрезал доступ приложению на уровне таблиц только этим таблицам и пусть что хочет то и творится) - написать процедуру в самом скуле (логику дерганья данных из файлов судя по всему вы знаете) и забыть о прокладке (приложении) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2014, 22:31 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Автогенерацию айдишников базой для нужной таблицы можно временно отключить и генерировать их в приложении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2014, 14:07 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
Но, самый правильный вариант - использовать временную буферную таблицу, вставить туда, потом процедурой перелить в основную таблицу. Я недавно тренировался так базу ФИАС заливать. Там 20 млн. записей. Примерно 30 минут на заливку в буферную таблицу. И 2 минуты на переливку из неё в постоянную. Лил через медленную сеть, быструю, на той-же машине, где сервер, играл с памятью, дисками. Лил как порциями разного размера, так и разом. Максимум из BuilkInsert выжалось 15 тыс. записей в секунду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2014, 14:24 |
|
||
|
Подскажите, как лучше организовать первичный ключ.
|
|||
|---|---|---|---|
|
#18+
__TT__TT__Имеется таблица [Operation], в которой на данный момент 985+ млн. записей. В таблице есть первичный ключ – bigint identity. Он также является внешним, для 6 таблиц связанных с [Operation]. В таблице [Operation] есть 4 поля определяющие уникальность (код подразделения – int, код офиса – int, дата – date, номер операции в течение дня – int). Есть задача: создать первичный ключ на основании 4 полей определяющих уникальность и заменить им имеющийся. Не надо трогать, то что работает. Просто создайте составной ключ на эти четыре поля и в свойствах укажите уникальность. Т.о. вы решите вашу задачу (проверка на уникальность 4 значений средствами БД) Не нужно будет перестраивать структуру БД. P.S. Холивар об преимуществах/недостатках естественных ключей будет долгим и нудным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2014, 07:58 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=38622445&tid=1540895]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
153ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
| others: | 257ms |
| total: | 508ms |

| 0 / 0 |

Извините, этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
... ля, ля, ля ...