Обложка канала

Oracle Developer👨🏻‍💻

Все о разработке в СУБД "Oracle" SQL, PL/SQL, оптимизация, архитектура, сертификации и многое другое.

Oracle Developer👨🏻‍💻

4 года назад
Открыть в
2️⃣ Вертикальное (EAV) Каждое свойство - это одна строка. Строка содержит: ссылку на родительскую сущность, ссылку на бизнесовый тип поля и само значение.
— справочник типов бизнес-полей
create table client_data_field(
 field_id   number(10) not null,
 field_name varchar2(100 char) not null
);

insert into client_data_field values(1, 'FIRST_NAME');
insert into client_data_field values(2, 'LAST_NAME');
insert into client_data_field values(3, 'MIDDLE_NAME');
insert into client_data_field values(4, 'BIRTH_DAY');

create table client_data_v(
  client_id   number(38) not null,
  field_id    number(10) not null,
  field_value varchar2(1000 char) not null   
);

insert into client_data_v values(777, 1, 'Иван');
insert into client_data_v values(777, 2, 'Иванов');
insert into client_data_v values(777, 4, to_char(date'1984-01-21','dd.mm.yyyy'));

Для поиска индексируются поля field_value, field_id. Если нужен поиск по нескольким свойствам, придется писать join для каждого критерия. Например поиск по last_name + др:
select ... 
  from client_data bd
  join client_data ln on ln.client_id = bd.client_id and ln.field_id = 1 and ln.field_value = ...
 where bd.field_id = 4
   and bd.field_value = ...;

При возрастании объема данных поиск может быть ооочень долгим. Надеюсь, принцип понятен. Подробней в ссылке ниже. 3️⃣ Другие варианты Я думаю, можно насобирать еще с десяток вариантов. Зависит от конкретных нужд системы. Например, хранить часть свойств горизонтально, часть в json в одном поле. Как предложил Филип в этом видео. ⚠️ Каждый из вариантов имеет свои плюсы и минусы. Формат поста не позволяет рассмотреть их все. —— Вернемся к задаче. 1️⃣ Требования: частое добавление новых свойств, нагруженная OLTP система. 🔸 Горизонтальное - нужно добавить новый столбец в таблицу client_data_h. Что выйдет? Скорее всего, ничего, т.к. система под нагрузкой - таблица заблокирована на изменение структуры. 🔸 Вертикальное - все сведется к вставке новой строки в client_data_field. После этого уже можно хранить свойство в client_data_v. 2️⃣ Требования: поиск по id клиента и бизнесовым свойствам. С поиском по id клиента - проблем нет в любом варианте. По нему мы без проблем можем достать технические и бизнесовые свойства вне зависимости от объема данных. 🔸 Горизонтальное - PK по id клиента 🔸 Вертикальное - PK по комбинации id клиента + fld_id. А вот с поиском клиентов по бизнесовым свойствам - проблема. Поиск в действительно большом объеме данных + по любому бизнес полю - это не задача OLTP. Если оператору хочется производить поиск в данных, придется придумывать некие workaround-решения заточенные под поиск (это может быть, параллельно существующая структура для хранения бизнес полей; совсем другая БД и т.п.). Если же данных не так что бы и много, то можем попробовать обойтись индексами: 🔸 Горизонтальное - нужно добавить новый индекс на новый столбец. С использованием опции online - это не большая проблема. 🔸 Вертикальное - у нас уже должен быть индекс на комбинацию полей (field_value, field_id). Ничего делать не нужно. В любом случае, стоит дополнительно обговорить с бизнесом, точно ли им нужен поиск, по всем ли полям и т.п. Выводы: для нашей задачи больше подходит вертикальное хранение свойств. Понравилась задача? Палец вверх 👍 Тема холиварная - можно обсудить в нашем ламповом чатике 😉 P.S. В определениях таблиц опущены всевозможные ограничения, FK, PK и т.п. #решениезадачи #проектирование Oracle Developer