powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Картотека
27 сообщений из 27, показаны все 2 страниц
Картотека
    #35806803
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте уважаемые,

Задача создать картотеку на SQL, в которой у карт произвольные атрибуты, которые можно в процессе эксплуатации расширять. Например, ФИО, Пол, Возраст, ... А затем производить выборки по значениям атрибутов. Картотека может содержать более 1 000 000 записей.

Сначала хотел сделать на трех таблицах (упрощенно) 1 Карты, 2 Атрибуты, 3 Кростаблица - атрибуты карт и в нее же класть значение параметра в тексте.

Вырисовываются проблемы 1)с Select сравнивать нужно параметры сгруппированные по карте. 2) Могут понадобиться операции над числовыми данными или датами, < > !=.

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

Проблема 2) Могут понадобиться операции над числовыми данными или датами, < > !=. Остается

Xml пользоваться нельзя по свыше данным установкам.

Если кто-нибудь встречался с такой занозой - направте в нужное русло плиз.

Модератор: Тема перенесена из форума "Microsoft SQL Server".
...
Рейтинг: 0 / 0
Картотека
    #35806869
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможна ли ситуация, когда у разных карточек разные атрибуты?
...
Рейтинг: 0 / 0
Картотека
    #35807198
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_L, не понял, чем тебе первый вариант не нравится?
По подробнее, pls

ЗЫ я бы его выбрал (только может быть чем-нибудь дополнил - от специфики)
...
Рейтинг: 0 / 0
Картотека
    #35807325
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть ещё третий вариант - у каточки сделать атрибуты просто в виде полей.

Если атрибуты совсем произвольные, то первый вариант, если количество ограниченное, расширяться будет постепенно, по мере развития системы, атрибуты используются в коде, в логике - то третий.
...
Рейтинг: 0 / 0
Картотека
    #35807353
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KrebА затем производить выборки по значениям атрибутов. Картотека может содержать более 1 000 000 записей.
Для начала неплохо определится, что из себя будут представлять выборки, как много полей в условиях запросов будет задействовано и будут ли сложные условия. Сами понимаете - на все случае жизни обычные OLTP сервера индексов не напасутся ;)
...
Рейтинг: 0 / 0
Картотека
    #35807577
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHSenya_L, не понял, чем тебе первый вариант не нравится?
По подробнее, pls

ЗЫ я бы его выбрал (только может быть чем-нибудь дополнил - от специфики)Разве я говорил, что не нравится? Просто уточнить хотел по атрибутам: 1) их переменное количество или постоянное, 2) типы атрибутов фиксированный или переменный, 3) допустим ли для всех атрибутов тип строковой? Я могу догадаться, какими будут ответы, но лучше переспросить.

И не то чтобы не нравиться, но смущает то, что
авторКартотека может содержать более 1 000 000 записей.
...
Рейтинг: 0 / 0
Картотека
    #35808116
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уточняю решение по варианту №1:

1) Сущность <Атрибуты> - собственно справочник, содержит поля:
Атрибут_ID - Суррогатный ключ
Атрибут_NAME - Название аттрибута
Атрибут_DEFAULT - Значение аттрибута по-умолчанию

Уникальный индекс (ключ) по Атрибут_ID
Уникальный индекс по Атрибут_NAME

особенности: при добавлении аттрибута в справочник - значение данного аттрибута автоматически добавляется всем аттрубутам карточек со значением по-умолчанию (Предлагаю физически в базу - так проще потом запросы делать).
При удалении - удалять записи из аттрибутов карточек.

2) Сущность <Карточки> - содержит экземпляры карточек, поля:
Карточка_ID - Суррогатный ключ
... - технические поля, например дата создания карточки

Уникальный индекс (ключ) по Карточка_ID

3) Сущность <Аттрибуты_карточек> - Список аттрибутов карточек. Поля:
Аттрибут_карточки_ID - Суррогатный ключ
Карточка_ID - Карточка
Атрибут_ID - Аттрибут
Значение - Строковое значение аттрибута

Уникальный индекс (ключ) по Аттрибут_карточки_ID
Уникальный индекс (ключ) по (Карточка_ID, Атрибут_ID)
Индекс по Карточка_ID
Индекс по Атрибут_ID
еще можно по (Атрибут_ID, Значение) и/или (Атрибут_ID, To_Date(Значение)) - для оракла, в MS сами напишите и т.д.

Больше всего объем будут занимать именно эти индексы. Они же примут на себя основную нагрузку в обеспечении производительности.

----------
Запрос с критериями:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT *
FROM Карточки  к
WHERE к.Карточка_ID IN ( SELECT  AK.Карточка_ID
                         FROM    Аттрибуты_карточек  AK
                         WHERE   AK.Атрибут_ID = (Select Атрибут_ID FROM Атрибуты WHERE Атрибут_NAME = 'Возраст')
                             AND AK.Значение >=  18 
                         INTERSECT   -- это типа И, для ИЛИ пишем UNION ALL
                         SELECT  AK.Карточка_ID
                         FROM    Аттрибуты_карточек  AK
                         WHERE   AK.Атрибут_ID = (Select Атрибут_ID FROM Атрибуты WHERE Атрибут_NAME = 'Пол')
                             AND AK.Значение = 'М'
)
- в принципе можно по другому написать, что производительнее у Вас - решать Вам.

Теоретически, можно три значения аттрибута хранить - как строку, число и дату, а использовать то, что нада, остальное - NULL. Потеряем в объеме, в производительности должны выиграть (наверно).
...
Рейтинг: 0 / 0
Картотека
    #35808120
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LИ не то чтобы не нравиться, но смущает то, что
авторКартотека может содержать более 1 000 000 записей.
Это не много.
Вот для аттрибутов карточек, если видов аттрибутов 50, то получаем уже 50 000 000 записей.
...
Рейтинг: 0 / 0
Картотека
    #35808162
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще один вариант:
две сущности, первая - карточка с аттрибутами, вторая - метаданные аттрибутов.

Нужно добавить аттрибут - расширьте таблицу (первую) и добавьте данные во вторую.
Первая - снужными типами данных и т.д.
Вторая таблица нужна только для сопоставления человеческих названий с названиями полей в БД (первой таблице), описания их типов - для построения нормального клиента.

А что?
СУБД зачем нужна?! Правильно, чтобы управлять. Вот и пусть управляет
...
Рейтинг: 0 / 0
Картотека
    #35808274
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHЕще один вариант:
две сущности, первая - карточка с аттрибутами, вторая - метаданные аттрибутов.А как это будет выглядеть с CREATE TABLE?
...
Рейтинг: 0 / 0
Картотека
    #35808302
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное спасибо за обсуждение,
Привожу картинку как это мне видится на данный момент (упрощенно).
Есть сущности Карты Атрибуты Типы.
Типы могут быть вложенными это свойство поддерживается таблицей Typedependens. С CardAttribute все понятно. Однако значение атрибута может иметь простой или составной тип. Объекты значений атрибутов сведены в ObjectValue.
Маленькая табличка AttribeteRegex это зародыш регулярных выражений для проверки правильности ввода значений объектов атрибутов.
Вариант с добавлением полей не подходит на мой взгляд т.к. придется менять запросы по выборке данных и клиентскую часть.
Для разных карт разные полностью атрибуты не будут это не нужно. Справочник один. А вот состав атрибутов может отличаться в соответствии с имеющимися данными. При добавлении нового атрибута добавлять его во все карты нет необходимости, т.к. параметры при этом не вводятся а хранить в БД пустые строки мне кажется не стоит. Если 1000 000 карточек, ввели новый параметр, то автоматом в CardAttribute появится 1 000 000 записей.
...
Рейтинг: 0 / 0
Картотека
    #35808306
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чего то картинка не зааттачилась
...
Рейтинг: 0 / 0
Картотека
    #35808328
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KrebДля разных карт разные полностью атрибуты не будут это не нужно. Справочник один.И ради чего тогда, простите, трахаете моск?! Одна таблица для карточек, возможно кое-какие справочные таблицы. Чего мудрить-то? Вы это все затеяли, чтобы при "Если 1000 000 карточек, ввели новый параметр, то автоматом в CardAttribute появится 1 000 000 записей."? Вообще-то есть дефолтные поля у таблиц на этот случай, есть также нуллябливые поля.


KOT MATPOCKuH, Я же не зря спрашивал афтора про переменный состав атрибутов ;)
...
Рейтинг: 0 / 0
Картотека
    #35808368
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuH,

Спасибо
...
Рейтинг: 0 / 0
Картотека
    #35808459
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuH,
Поясните, пожалуйста как быть, если значения параметров например int или Datetime. В таблице значений они текстовые,
а искать используя Cast( as ) - не Гуд.
СУБД PosgreSQL 8.3. Идею использовать индексы адаптированные к типу скрытому в varchar не уловил.

и/или (Атрибут_ID, To_Date(Значение)) - для оракла, в MS сами напишите и т.д.

С уважением
...
Рейтинг: 0 / 0
Картотека
    #35809182
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kreb,

Вы можете объяснить, зачем Вам понадобилась модель EAV, если у ВСЕХ карточек в картотеке количество атрибутов одинаковое и состав (как я понял) один и тот же? Добавить столбец в процессе эксплуатации очень легко: alter table ... add column. Может я чего-то недопонимаю?
...
Рейтинг: 0 / 0
Картотека
    #35810285
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LKOT MATPOCKuHЕще один вариант:
две сущности, первая - карточка с аттрибутами, вторая - метаданные аттрибутов.А как это будет выглядеть с CREATE TABLE? Не CREATE TABLE, а ALTER TABLE ADD COLUMN
...
Рейтинг: 0 / 0
Картотека
    #35810296
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LKrebДля разных карт разные полностью атрибуты не будут это не нужно. Справочник один.И ради чего тогда, простите, трахаете моск?! Одна таблица для карточек, возможно кое-какие справочные таблицы. Чего мудрить-то? Вы это все затеяли, чтобы при "Если 1000 000 карточек, ввели новый параметр, то автоматом в CardAttribute появится 1 000 000 записей."? Вообще-то есть дефолтные поля у таблиц на этот случай, есть также нуллябливые поля.


KOT MATPOCKuH, Я же не зря спрашивал афтора про переменный состав атрибутов ;)Дак я-то понял, просто ответа от автора не было какое-то время, вот и предлогал...
...
Рейтинг: 0 / 0
Картотека
    #35810306
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHSenya_LKOT MATPOCKuHЕще один вариант:
две сущности, первая - карточка с аттрибутами, вторая - метаданные аттрибутов.А как это будет выглядеть с CREATE TABLE? Не CREATE TABLE, а ALTER TABLE ADD COLUMNЯ имел ввиду DDL модели EAV. А то, что здесь нужна одна таблица - автор молчит, хоть ты развей мои сомнения. Автор-то забил.
...
Рейтинг: 0 / 0
Картотека
    #35810315
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KrebKOT MATPOCKuH,
Поясните, пожалуйста как быть, если значения параметров например int или Datetime. В таблице значений они текстовые,
а искать используя Cast( as ) - не Гуд.
СУБД PosgreSQL 8.3. Идею использовать индексы адаптированные к типу скрытому в varchar не уловил.

и/или (Атрибут_ID, To_Date(Значение)) - для оракла, в MS сами напишите и т.д.

С уважениемКак вариант предлогалось следующее: в таблице значений аттрибутов карточек хранить не одно поле значений типа текст, а три поля: текст, дата, число. Что именно используется для конкретного параметра - описать в справочнике аттрибутов. А в запросах - вы же сами знаете, что возраст - это число, а дата рождения - это дата. Соответствующие поля и используете, когда пишите SELECT. В "универсальных" запросах - через справочник получаете тип, по нему - используете соответствующее поле.
...
Рейтинг: 0 / 0
Картотека
    #35810325
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kreb... СУБД PosgreSQL 8.3....
А чего:
Модератор: Тема перенесена из форума "Microsoft SQL Server".
?????
...
Рейтинг: 0 / 0
Картотека
    #35810334
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_LKOT MATPOCKuHSenya_LKOT MATPOCKuHЕще один вариант:
две сущности, первая - карточка с аттрибутами, вторая - метаданные аттрибутов.А как это будет выглядеть с CREATE TABLE? Не CREATE TABLE, а ALTER TABLE ADD COLUMNЯ имел ввиду DDL модели EAV. А то, что здесь нужна одна таблица - автор молчит, хоть ты развей мои сомнения. Автор-то забил.Не понял, какие сомнения развеить? Что нужно автору - ему и выбирать, мы только предлагаем варианты
...
Рейтинг: 0 / 0
Картотека
    #35810343
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что, посчитать некошерно?
Из-за такой ерундовины так ломать нормальную структуру с одной таблицей?
Сползаю под стул... :)

> Автор: KOT MATPOCKuH
> Kreb
> KOT MATPOCKuH,
> Поясните, пожалуйста как быть, если значения параметров
> например int или Datetime. В таблице значений они текстовые,
> а искать используя Cast( as ) - не Гуд.
> СУБД PosgreSQL 8.3. Идею использовать индексы адаптированные к
> типу скрытому в varchar не уловил.
>
> и/или (Атрибут_ID, To_Date(Значение)) - для оракла, в MS сами
> напишите и т.д.
>
> С уважением
> Как вариант предлогалось следующее: в таблице значений аттрибутов
> карточек хранить не одно поле значений типа текст, а три поля: текст,
> дата, число. Что именно используется для конкретного параметра - описать в
> справочнике аттрибутов. А в запросах - вы же сами знаете, что возраст -
> это число, а дата рождения - это дата. Соответствующие поля и используете,
> когда пишите SELECT. В "универсальных" запросах - через справочник
> получаете тип, по нему - используете соответствующее поле.
>

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Картотека
    #35810356
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: KOT MATPOCKuH
> Не понял, какие сомнения развеить? Что нужно автору - ему и выбирать,
> мы только предлагаем варианты
>

Я сомневался, правильно я понял постановку задачи автора. В смысле нужен ли
ему вообще EAV или нет. Я думаю, что нет. И в своем первом топике не
напрасно уточнил про состав атрибутов у карточек.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Картотека
    #35810450
KOT MATPOCKuH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Senya_L
А что, посчитать некошерно?
Из-за такой ерундовины так ломать нормальную структуру с одной таблицей?
Сползаю под стул... :)

Держись!!!!

Да, некошерно из-за объемов данных и универсальности вопроса.
Если бы карточек было 100-200 - было бы без разницы, но когда начинаем считать милионы...
Я в одном из своих предложений показывал, что по полю "значение" таблицы значений аттрибутов карточек нужен индекс. Иначе, для любого запроса с ограничением значений аттрибутов будем иметь FULL TABLE SCAN, т.е. полный просмотр большой таблицы.
В оракле, например, можно сделать одно текстовое поле, но сделать индексы:
- по самому, полю
- по функциям преобразования значения поля к числу, дате и др..
Тогда SELECT * From T Where to_number(val) = 10, при наличии индекса на to_number(val) будет выполняться по индексу очень быстро. (Кстати, как следствие такого решения для упращения запросов я предлгал прописывать значениями по-умолчанию значение нового аттрибута во всех карточках)

В других СУБД чаще всего такое невозможно, а т.к. автор задал вопрос на этот форум, то нужно универсальное решение, не зависящее от СУБД.
...
Рейтинг: 0 / 0
Картотека
    #35810535
Senya_L
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KOT MATPOCKuHSenya_L
А что, посчитать некошерно?
Из-за такой ерундовины так ломать нормальную структуру с одной таблицей?
Сползаю под стул... :)

Держись!!!!

Да, некошерно из-за объемов данных и универсальности вопроса.
Если бы карточек было 100-200 - было бы без разницы, но когда начинаем считать милионы...
Я в одном из своих предложений показывал, что по полю "значение" таблицы значений аттрибутов карточек нужен индекс. Иначе, для любого запроса с ограничением значений аттрибутов будем иметь FULL TABLE SCAN, т.е. полный просмотр большой таблицы.
В оракле, например, можно сделать одно текстовое поле, но сделать индексы:
- по самому, полю
- по функциям преобразования значения поля к числу, дате и др..
Тогда SELECT * From T Where to_number(val) = 10, при наличии индекса на to_number(val) будет выполняться по индексу очень быстро. (Кстати, как следствие такого решения для упращения запросов я предлгал прописывать значениями по-умолчанию значение нового аттрибута во всех карточках)

В других СУБД чаще всего такое невозможно, а т.к. автор задал вопрос на этот форум, то нужно универсальное решение, не зависящее от СУБД.Прости, но не согласен совершенно. Из-за одного "универсального" запроса такое выделывать? Увольте.

Если уж речь зашла про оптимизацию.
Во-первых, индексы по полям COMPUTED BY есть не только в Оракле.
Во-вторых, пример (конечно, грубый, но из этой оперы :)):
Код: plaintext
1.
2.
select * from Tbl
where getdate() - Tbl.[birth_day] <  23 
индекс не испольузется. То же самое
Код: plaintext
1.
2.
select * from Tbl
where Tbl.[birth_day] > getdate() -  23  
используется.

PS. Коль здешняя ветка по академическим методам проектирования, то надо сначала быть уверенным, что все стандартные методы оптимизации исчерпаны структуры. А в данном случае это далеко не так.
...
Рейтинг: 0 / 0
Картотека
    #35811709
Kreb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KOT MATPOCKuH,

Спасибо за ваш вариант. Почитал доку по Oracle с индексами разобрался. Схема ваша совпала с нашей при коллективном обсуждении. Тему можно закрыть. Спасибо всем.
С уважением.
...
Рейтинг: 0 / 0
27 сообщений из 27, показаны все 2 страниц
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Картотека
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]