Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Добрый день!
У меня вопрос из области "Бест практикс".

Некоторое время у нас ведется религиозный спор на заданную тему топика.
В давние времена в десятке таблиц были созданы поля
Property bigint
, в которые вялится куча разномастных битов.
Для поддержки работы с ними создаются скалярные функции, дающие "относительно удобный" доступ
таблички небольшие - сотни, редко тысячи записей

Главный и пока единственный аргумент "за"
Большое количество раскатанных по стране баз, которые мы постоянно обновляем. Обновить содержимое Интового поля при добавление нового "свойства-бита" значительно проще, чем менять структуру и добавлять в нее новое поле

Аргументы против
1. Нарушение нормализации базы данных. В одной ячейке лежат разные по сути значения
2. Не наглядно. Надо постоянно лезть в функции с описанием констант, при нормальных названиях полей информация о структуре сразу под ногами
3. не удобно писать обращения к полям

select 
	Catalog_Code = C.Code,
	Allow_Null = 	case 
						when F.Field_Property & [nsi].[fn_Constant_bit]('nsi.Field.Property.Nullable') > 0 then 1
						else 0 
				end
from nsi.v_Main_Akey_Field F
inner join nsi.Catalog C on C.ID = F.Catalog_ID

4. скалярная функция с контантой будет дергаться для каждой строки, соответственно ей сначало желательно положить в переменную, что увеличивает неудобство

вопрос Кто-нибудь еще пользуется подобным подходом, есть какие-то еще аргументы?
9 окт 14, 12:32    [16681164]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mike_za
1. Нарушение нормализации базы данных. В одной ячейке лежат разные по сути значения

5я НФ - это идеал. Который не всем нужен

Mike_za
2. Не наглядно. Надо постоянно лезть в функции с описанием констант, при нормальных названиях полей информация о структуре сразу под ногами

Для визуализации есть другие объекты

Mike_za
3. не удобно писать обращения к полям

Субъективный взгляд. Создайте одно представление с разбивкой по "полям".

Mike_za
4. скалярная функция с контантой будет дергаться для каждой строки, соответственно ей сначало желательно положить в переменную, что увеличивает неудобство

А зачем скалярная функция дял работы с битовой маской ?
9 окт 14, 12:40    [16681204]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Crimean
Member

Откуда:
Сообщений: 13148
не панацея, но вариант. добавьте вычисляемых bit полей, как это делает MS
IsSome as ( Property & 0x0800 <> 0 )
вопрос с расшифровками частично отпадет
9 окт 14, 12:43    [16681225]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Побейте на битовые поля и не страдайте непонятными заболеваниями :)
9 окт 14, 13:18    [16681492]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Что касается аргументации "проще", то это не так, не проще, столбец добавляется без каких-либо затрат времени.
9 окт 14, 13:20    [16681505]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Glory
5я НФ - это идеал. Который не всем нужен

так тут разве не первая нормальная форма нарушена?
автор
Чтобы привести таблицу к 1НФ, нужно соблюсти два правила:
1.Атомарность или неделимость. Каждая колонка должна содержать одно неделимое значение.
2.Таблица не должна содержать повторяющихся колонок или групп данных.


автор
А зачем скалярная функция для работы с битовой маской ?

что бы обращаться к битам не по номеру а по "текстовому имени"
а как было бы правильней?

автор
не панацея, но вариант. добавьте вычисляемых bit полей, как это делает MS
IsSome as ( Property & 0x0800 <> 0 )
вопрос с расшифровками частично отпадет

а как же вопрос с записью? в 2х местах будет вшит номер бита?

автор
Побейте на битовые поля и не страдайте непонятными заболеваниями :)

это и есть один из 2х вариантов, я же пришел за аргументами

автор
Что касается аргументации "проще", то это не так, не проще, столбец добавляется без каких-либо затрат времени.
в нашей системе все же это сложнее. у нас есть уровень метаописания данных и сами данные. Сами данные обновляются постоянно и штатно. Обновление структуры базы данных - это дополнительные действия пользователей
9 окт 14, 13:45    [16681733]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mike_za
так тут разве не первая нормальная форма нарушена?

Нет.

Mike_za
что бы обращаться к битам не по номеру а по "текстовому имени"
а как было бы правильней?

Т.е. без скалярной функции нельзя сделать "обращение по текстовому имени" что ли ?
9 окт 14, 13:49    [16681759]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Glory, табличная инлайн функция? Вы можете привести ваш вариант, или мы играем в угадайку?
9 окт 14, 13:56    [16681809]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Glory, я привел неправильное определение 1НФ? или несколько битов невозможно разделить на отдельные поля?
9 окт 14, 13:57    [16681823]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
Mike_za
Glory, табличная инлайн функция? Вы можете привести ваш вариант, или мы играем в угадайку?

declare @BitFlag table (flag int,name varchar(10))
insert into @BitFlag values(2,'flag1'),(4,'flag2'),(8,'flag3')
declare @data table (id int,flag int,data varchar(20))
insert into @data values(1,6,'flag1,flag2'),(2,10,'flag1,flag3'),(3,12,'flag2,flag3')

select d.* 
from @data d
join @BitFlag f on f.name='flag1' and d.flag&f.flag>0
9 окт 14, 13:57    [16681824]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
LexusR, а как мне потом обращаться к этим битам из десятка процедур?
джоин на таблицу более удобен чем константная функция?
9 окт 14, 14:00    [16681842]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mike_za
Glory, я привел неправильное определение 1НФ? или несколько битов невозможно разделить на отдельные поля?

А номер паспорта можно разделить на цифры и буквы, например. А их в свою очередь на биты.
Проектирование таблицы начинается с опредления аттрибутов.
Как определю аттрибуты, так и буду нормальные формы делать.


Mike_za
Glory, табличная инлайн функция? Вы можете привести ваш вариант, или мы играем в угадайку?

Какую угадайку ?
Зачем для битовой операции нужна функция, если есть битовые операнды ?
9 окт 14, 14:04    [16681880]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
create function dbo.fnBitMaskToTable
(
 @m bigint
)
returns table as
return (
 select
  cast(case when @m & 1 = 0 then 0 else 1 end as bit) as Column1,
  cast(case when @m & 2 = 0 then 0 else 1 end as bit) as Column2,
  ...
);
9 окт 14, 14:06    [16681888]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
step_ks
Member

Откуда:
Сообщений: 936
Mike_za
4. скалярная функция с контантой будет дергаться для каждой строки, соответственно ей сначало желательно положить в переменную, что увеличивает неудобство

функцию нельзя заставить быть детерминированной ?
9 окт 14, 14:07    [16681902]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
step_ks, в зависимости от текстовой константы, она всегда возвращает числовую константу.
а можно подробнее?
9 окт 14, 14:08    [16681914]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
функцией от INVM
if OBJECT_ID('dbo.fnBitMaskToTable') is not null drop function dbo.fnBitMaskToTable
go
create function dbo.fnBitMaskToTable (@m bigint)
returns table as
return (
 select
  cast(case when @m & 1 = 0 then 0 else 1 end as bit) as flag0,
  cast(case when @m & 2 = 0 then 0 else 1 end as bit) as flag1,
  cast(case when @m & 4 = 0 then 0 else 1 end as bit) as flag2,
  cast(case when @m & 8 = 0 then 0 else 1 end as bit) as flag3
)
go

declare @BitFlag table (flag int,name varchar(10))
insert into @BitFlag values(2,'flag1'),(4,'flag2'),(8,'flag3')
declare @data table (id int,flag int,data varchar(20))
insert into @data values(1,6,'flag1,flag2'),(2,10,'flag1,flag3'),(3,12,'flag2,flag3')

select d.*, f.flag1
from @data d
cross apply dbo.fnBitMaskToTable (flag) f
where flag1=1
9 окт 14, 14:18    [16681985]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
Mike_za
step_ks, в зависимости от текстовой константы, она всегда возвращает числовую константу.
а можно подробнее?

сделать функцию детерминированной
create function dbo.MyFunc (@I int) 
returns int
as
begin
return(select @I + 10)
end
GO

SELECT OBJECTPROPERTYEX(OBJECT_ID('dbo.MyFunc'), 'IsDeterministic')
GO

ALTER function dbo.MyFunc (@I int) 
returns int
WITH SCHEMABINDING
as
begin
return(select @I + 10)
end
GO

SELECT OBJECTPROPERTYEX(OBJECT_ID('dbo.MyFunc'), 'IsDeterministic')
GO
drop function dbo.MyFunc
go
9 окт 14, 14:24    [16682052]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
автор
в нашей системе все же это сложнее. у нас есть уровень метаописания данных и сами данные. Сами данные обновляются постоянно и штатно. Обновление структуры базы данных - это дополнительные действия пользователей


Так это ограничения вашего фреймфорка, а не сервера. Что-то в консерватории надо подправить. Пользователи не должны накатывать обновления базы :)
9 окт 14, 14:35    [16682154]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
step_ks
Member

Откуда:
Сообщений: 936
Mike_za
step_ks, в зависимости от текстовой константы, она всегда возвращает числовую константу.
а можно подробнее?

Deterministic and Nondeterministic Functions
Сможете сделать детерминированной - будет вызываться 1 раз.
9 окт 14, 15:03    [16682357]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
LexusR, сделал...
SELECT OBJECTPROPERTYEX(OBJECT_ID('[nsi].[fn_Constant_bit]'), 'IsDeterministic') = 1
но в профайлере вызовы так и остались по количеству строк

SP:StmtCompleted	SELECT
		@ResultVar = case @Constant_Name
			when 'nsi.Catalog.Property.HasVariants' then 1
			when 'nsi.Catalog.Property.DataSource' then 2
			when 'nsi.Catalog.Property.IntendedForDataColumn' then 4
			when 'nsi.Catalog.Property.NotPublicable' then 8
9 окт 14, 15:36    [16682562]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Glory, номер паспорта - это отдельное неделимое свойство. если его разрезать на 3 части, то по отдельности они не будут нести смысла
в моей же ситуации это абсолютно независящие друг от друга свойства, их смысл в отдельном использовании, и вместе они никогда нигде и никому не нужны.


when 'nsi.Catalog_Relation.Property.Disabled' then 2
when 'nsi.Catalog_Relation.Property.Generate_Parent_Combination' then 4
when 'nsi.Catalog_Relation.Property.Cascade_Delete' then 8
when 'nsi.Catalog_Relation.Property.Delete_Parent_Combination' then 16
when 'nsi.Catalog_Relation.Property.Cascade_Update' then 32
when 'nsi.Catalog_Relation.Property.NotUpdatable' then 0 


автор
Зачем для битовой операции нужна функция, если есть битовые операнды ?

для битовой операции функция не нужна. Она нужна для получения номера бита, к которому желают обратиться
9 окт 14, 15:45    [16682621]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mike_za
для битовой операции функция не нужна. Она нужна для получения номера бита, к которому желают обратиться

Фейспалм.
Создать объект, где каждый бит будет отображен в виде отдельного поля, что мешает ?
9 окт 14, 15:59    [16682701]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
автор
Фейспалм.
Создать объект, где каждый бит будет отображен в виде отдельного поля, что мешает ?

1. так все же первая нормальная форма в БД нарушена?
2. если речь идет о таблице. то суть моего топика и была в аргументах за отдельные поля. Или речь о слое над БД? вьюхи срезы?
9 окт 14, 16:05    [16682736]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Или речь о слое над таблицей БД? вьюхи срезы? (описался)
9 окт 14, 16:06    [16682741]     Ответить | Цитировать Сообщить модератору
 Re: много битов в BigInt поле  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mike_za
1. так все же первая нормальная форма в БД нарушена?

Нарушает ли 1ю форму хранение номера паспорта целиком в той же таблице, а не отдельно каждого его символа в другой таблице ?

Mike_za
2. если речь идет о таблице. то суть моего топика и была в аргументах за отдельные поля. Или речь о слое над БД? вьюхи срезы?

Ваш вопрос о том, как хранить данные, как оперировать или или как их визуализировать?
9 окт 14, 16:09    [16682762]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить