вопрос по планированию(SQL Server)

User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

вопрос по планированию(SQL Server)

Post by katit »

вопрос по планированию(SQL Server).

Я делаю таблицу:
TableA (TextKey (Int), Text (text)
и куча других таблиц ею пользуются
TableB (MyKey (Int), ..... , TextKey(Int) FK)
TableC (MyKey (Int), ..... , TextKey(Int) FK)
TableD (MyKey (Int), ..... , TextKey(Int) FK)

Хорошая это идея или нет?
Я из соображений таких:
1. FTS надо на одну таблицу вешать
2. Остальные таблицы полегче, а эти данные только изредка нужны. Т.е. в большинстве случаев таблицы будут query сами по себе
3. Если вдруг изменить тип то легче в одном месте.
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

Внутреняя реализация LOB сама по себе примерно так и сделана (на самом деле намного сложнее, но идея похожа). Поэтому единственное заметное преимущество, которое Вы получаете - это централизованная манипуляция FTS индексами как Вы уже заметили.
Cheers
User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: вопрос по планированию(SQL Server)

Post by katit »

tengiz wrote:Внутреняя реализация LOB сама по себе примерно так и сделана (на самом деле намного сложнее, но идея похожа). Поэтому единственное заметное преимущество, которое Вы получаете - это централизованная манипуляция FTS индексами как Вы уже заметили.


Хм. Понятно.
Все равно мучаюсь в сомнениях. Надо ли мне этот текст. Это как вы наверное догадались для веба чтобы хранить HTML. Как правило максимальной длинны NVarChar хватает (95% случаев).

Читал BOL, но все равно не допер. Я NText использую как
параметр в SP или как столбец в SELECT. Там написано что если больше 8к то надо API использовать. Но у меня и так работает (Для больших данных)
Работает - ли LIKE для них ?

Какие реальные минусы в использовании этого типа?

Еще вопрос.
Я вот что делаю для того чтобы добиться "atomic update".
Делаю XML на клиенте (таблицы ведь нельзя передавать). После в SP уже все в транзакции делаю.

Это что-то распространенное или я засложно ворочу?

Вопрос по ADO. В VB я вместо этого XML открывал соединение, делал #Table,
заполнял ее с клиента, а затем вызывал SP.

В .NET(ASP.NET) я не совсем понимаю как соединение работает. Что такое connection pooling? Значит - ли это что разные сессии будут друг друга #Table видеть ?

Еще вопрос по планированию..
Есть надобность сохранять name/value пары для многих entities. Кажется проше выделить текст для них и туда XML пихать (на стороне базы эти данные не нужны)
Или не полениться, сделать кучу маденьких таблиц ?

Еще вопрос по производительности (для веб-программеров)
Часто вижу такое:
TableA (A PK, NoRecordsInB...)
TableB (B PK, A FK, ....)

Вот это NoRecordsInB меня сильно бесит. Я в таких случаях делаю view или пишу subquery.
Вот неужели так на производительность это влияет ?



Спасибо
(блин, много вопросов получилось)
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

LOB колонок лучше конечно избегать, когда это возможно. LIKE для них работает. Минусы - неудобства: нельзя использовать строковые функции когда нужно добираться дальше 8K, нельзя строить индексы и агрегаты, проблема с использованием в триггерах (кром INSTEAD OF).
Я вот что делаю для того чтобы добиться "atomic update". Делаю XML на клиенте (таблицы ведь нельзя передавать). После в SP уже все в транзакции делаю.
Не уверен, что я понимаю - а почему нельзя открыть транзакцию с клиента и выполнить её в несколько шагов? Это, конечно, может получиться медленнее, чем процедура, но когда произвотидельность не критична, то атомарности можно добиваться и без процедур.
Вопрос по ADO. В VB я вместо этого XML открывал соединение, делал #Table, заполнял ее с клиента, а затем вызывал SP. В .NET(ASP.NET) я не совсем понимаю как соединение работает. Что такое connection pooling? Значит - ли это что разные сессии будут друг друга #Table видеть?

connection pooling позволяеть переиспользовать соединение, с которым уже никто не работает. соответвенно, никакие два активных логических соединения не будут разделять одно физическое. Поэтому та же самая техника с временными таблицами должна нормально работать.
Есть надобность сохранять name/value пары для многих entities. Кажется проше выделить текст для них и туда XML пихать (на стороне базы эти данные не нужны) Или не полениться, сделать кучу маденьких таблиц ?

А зачем нужна куча маленьких таблиц? Нельзя разве создать одну, добавив к паре имя/значение ещё и идентификатор объекта и типа объекта? Или я что-то упустил?
Cheers
User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: вопрос по планированию(SQL Server)

Post by katit »

tengiz wrote:LOB колонок лучше конечно избегать, когда это возможно. LIKE для них работает. Минусы - неудобства: нельзя использовать строковые функции когда нужно добираться дальше 8K, нельзя строить индексы и агрегаты, проблема с использованием в триггерах (кром INSTEAD OF).

А LIKE это строковая функция ?

Не уверен, что я понимаю - а почему нельзя открыть транзакцию с клиента и выполнить её в несколько шагов? Это, конечно, может получиться медленнее, чем процедура, но когда произвотидельность не критична, то атомарности можно добиваться и без процедур.

Вот тут и вопрос. Медленнее-ли. Т.к. на кленте этот XML конструируется, а сервер его парсит. Делал т.к. непонимал следующий пункт.

connection pooling позволяеть переиспользовать соединение, с которым уже никто не работает. соответвенно, никакие два активных логических соединения не будут разделять одно физическое. Поэтому та же самая техника с временными таблицами должна нормально работать.
Так если логическое соединение создало #Table то второе логическое соединение ее будет видеть. Ведь таблица только вместе с физ. соединением помрет. Или сам SQL Server знает про это логическое соединение ?
А зачем нужна куча маленьких таблиц? Нельзя разве создать одну, добавив к паре имя/значение ещё и идентификатор объекта и типа объекта? Или я что-то упустил?

Можно. Но я почему-то этот вариант откидывал сразу за некрасивостью. Или практика распространенная ? Как например без триггера RI делать?
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

katit wrote:А LIKE это строковая функция ?
LIKE - это не функция. Функции - это, например, SUBSTRING, PATINDEX и пр. Они все работают только с первыми 8K текста.

Так если логическое соединение создало #Table то второе логическое соединение ее будет видеть. Ведь таблица только вместе с физ. соединением помрет. Или сам SQL Server знает про это логическое соединение?
Каждый раз когда физическое соединение выбирается из пула, драйвером выполняется специальная серверная процедура, которая чистит грязь, оставшуюся от предыщущего логического соединения.

Можно. Но я почему-то этот вариант откидывал сразу за некрасивостью. Или практика распространенная ? Как например без триггера RI делать?
А какие проблемы с декларативной RI Вы имеете в виду?
Cheers
User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: вопрос по планированию(SQL Server)

Post by katit »

tengiz wrote:А какие проблемы с декларативной RI Вы имеете в виду?


Например каскадное удаление. Или просто FK.
Как я могу проверить его если фактически таблица имеет много парентов ?
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

katit wrote:Как я могу проверить его если фактически таблица имеет много парентов ?
Судя по тому, что было написано выше Вам достаточно будет иметь композитный первичный ключ (id типа объекта, id атрибута) в master-таблице и, соответственно, композитный внешний ключ в detail. Или у Вас там что-то более сложное на самом деле?
Cheers
User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: вопрос по планированию(SQL Server)

Post by katit »

tengiz wrote:Судя по тому, что было написано выше Вам достаточно будет иметь композитный первичный ключ (id типа объекта, id атрибута) в master-таблице и, соответственно, композитный внешний ключ в detail. Или у Вас там что-то более сложное на самом деле?


Пример(чтобы убедиться что мы про одно говорим):
TableA (AKey PK, ....)
TableB (BKey PK, ... )
TableC (CKey PK, ...)

TableAChild (AKey FK, name, value)
TableBChild (BKey FK, name, value)
TableCChild (CKey FK, name, value)


Вы предагаете:

TableAllChild (ParentType, ParentKey FK, name, value)
(ParentType, ParentKey) - PK

ParentType будет ме говорить о том из какой таблицы ParentKey берется.
так вот как мне создать RI (без триггеров) чтобы при удалении из Table A удалились соотв. записи из TableAllChild.

Или как я сделаю FK на TableAllChild чтобы разрешить только правильные ParentType, ParentKey ?
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

Сделайте TableA, TableB, TableC и TableAllChild зависимыми от одной мастер-таблицы и соберите там всё общее, что есть в этих таблицах. Все удаления делайте из неё:

Code: Select all

create schema blah

create table master (
   objid int, type tinyint,
   primary key (objid, type))

create table TableA (
   objid int, type tinyint default (1) check (type = 1),
   primary key (objid),
   foreign key (objid, type) references master on delete cascade)

create table TableB (
   objid int, type tinyint default (2) check (type = 2),
   primary key (objid),
   foreign key (objid, type) references master on delete cascade)

create table TableC (
   objid int, type tinyint default (3) check (type = 3),
   primary key (objid),
   foreign key (objid, type) references master on delete cascade)

create table AllDetail (
   objid int, type tinyint, attributeName sysname, attributeValue sql_variant,
   unique (objid, type, attributeName),
   foreign key (objid, type) references master on delete cascade)
go

deny delete on TableA to public
deny delete on TableB to public
deny delete on TableC to public

deny insert, update on TableA (type) to public
deny insert, update on TableB (type) to public
deny insert, update on TableB (type) to public
go
Cheers
User avatar
katit
Уже с Приветом
Posts: 23804
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: вопрос по планированию(SQL Server)

Post by katit »

Интересно. Пример хороший, но не думаю что мне пойдет. Делать удаления из другой таблицы не есть красиво. И не нравится мне столбец Type. А вообще спасибо за код. Много интерестного для меня.

Вот только не могу найти
[cpde]attributeName sysname, [/code]
что за sysname тип?

И никогда не использовал sql_variant.
Можно-ли как-то узнать тип данных которые сохранены.
Типа как TypeOf в VB
Вроде в BOL ничего такого не вижу.
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Re: вопрос по планированию(SQL Server)

Post by tengiz »

katit wrote:Интересно. Пример хороший, но не думаю что мне пойдет. Делать удаления из другой таблицы не есть красиво. И не нравится мне столбец Type. А вообще спасибо за код. Много интерестного для меня.

Это уже Вам выбирать - для Вашей задачи больше никак не получится: если хотите меньше кода и больше декларативности, то нужно добавить слегка избыточности в данные. Если не хочется избыточности - тогда будет больше кода и меньше стандартных декларативных ограничений целостности.
Вот только не могу найти... sysname,...Можно-ли как-то узнать тип данных которые сохранены. Типа как TypeOf в VB

http://msdn.microsoft.com/library/defau ... s_4w89.asp
http://msdn.microsoft.com/library/defau ... b_7msw.asp
Cheers

Return to “Вопросы и новости IT”