помеченные размеры в хранилище данных - PullRequest
1 голос
/ 13 апреля 2011

В моем хранилище данных у меня есть измерение, где каждая запись может иметь один или несколько тегов. Есть ли какие-либо прямые способы моделирования измерения с разными тегами?

Моей первоначальной идеей было сохранить разделенный запятыми список, а затем использовать функцию MySQL: s FIND_IN_SET () для проверки наличия тега. Это позволяет мне нарезать данные.

Но как мне смоделировать мою схему, если я хочу иметь возможность группировать по тегам?

Пример:

Два продукта: продукт A и продукт B. A помечен как "foo", "bar". B помечен как "бар", "баз".

Запрос: суммы продаж, сгруппированные по тегу товара. Группа для тега "bar" должна включать продажи для продуктов A и B:

foo -> sales for A
bar -> sales for B and A
baz -> sales for C

Ответы [ 3 ]

1 голос
/ 13 апреля 2011

Например, вы можете хранить данные, дублированные тегом.

Если у вас есть продажи a = 10 foo + bar и b = 20 bar + baz, вы можете хранить их следующим образом.

    sales_by_tag_facts
    id, tag, sale_id, amount, is_primary_record
    1   foo  A        10     true
    2   bar  A        10     false
    3   bar  B        20     true
    4   baz  B        20     false

select sum(amount) from sales_by_tag_facts group by tag; // by tag
select sum(amount) from sales_by_tag_facts where is_primary_record=true; // without tag.
0 голосов
/ 14 апреля 2011

Почему бы не перенести тяжелую работу с отчетности на резервирование транзакции

Вы можете добавить новую таблицу с именем:

TagTotal, в которой хранится общая сумма на тег иобновляется с каждой транзакцией через триггер BEFORE (AFTER) _UPDATE_EACH.

Дополнительные поля / таблица

Если у вас есть 2 дополнительных поля в product table:

product.amount    decimal(10,2) running total of sales to date
product.last_sale date          date of the last sale

И таблица итоговых тегов выглядит следующим образом.

tag.id primary autoinc    
tag.tagstr varchar(25)     
tag.amount decimal(10,2)
tag.date_from date   #dates to keep the running totals per month/week/day.
tag.date_to   date

псевдокод

CREATE TRIGGER ai_sales_each AFTER INSERT ON sales FOR EACH ROW
BEGIN
  UPDATE product SET product.amount = product.amount + new.amount,
    product.last_sale = sale.date
END

CREATE TRIGGER au_product_each AFTER UPDATE ON product FOR EACH ROW
BEGIN
  DECLARE AllTags VARCHAR(255);
  DECLARE ThisTag VARCHAR(25);

  IF old.tags <> new.tags THEN BEGIN
    reorganize the running totals in the tagtotal table.
  END; END IF;

  SET AllTags = new.tags;
  WHILE AllTags has more tags BEGIN
    SET ThisTag = NextTag(AllTags);
    UPDATE TagTotals SET amount = amount + new.amount
      WHERE TagTotals.tagstr = ThisTag 
      AND new.last_date BETWEEN TagTotals.date_from AND TagTotals.date_to;
  END; END WHILE; 

Теперь, если выЧтобы получить итоги продаж по тегам, вы можете просто выбрать их из таблицы тегов.
Что даст мгновенный результат.

0 голосов
/ 14 апреля 2011

Я бы рекомендовал против этого, это идет вразрез с правилами нормализации.
См. Я продолжаю портить 1NF
Или читать сообщения под тегом нормализации .

Предложение по редизайну для таблиц

Если вы создаете тег и таблицу тегов, например, так.вот так.

table product
  id autoincement integer primary index
  desc varchar(255)
  barcode, price, whatever ...

оператор выбора для поиска товаров по тегу

Чем можно искать статьи, соответствующие тегу, следующим образом.

select * from product
inner join taglink on (product.id = taglink.product_id)
inner join tag on (taglink.tag_id = tag.id)
where tag.tag_str in ('foo','bar','baz');

выберите оператор для отображения тегов для каждого продукта

select tag_str from tag
inner join taglink on (taglink.tag_id = tag.id)
inner join product on (taglink.product_id = product.id)
where product.barcode = '4548215' or product.desc like 'OMG Po%'

Добавление новых тегов

Чтобы добавить новый тег, просто

insert into tag (id, tag_str) values (
  null /*remember autoincrement*/
  ,'Mytag');

привязка тега

Чтобы связать тег с продуктом

set @product_id = 10;
set @tag_id = 1;
...or...
select @product_id:= product.id from product where product.barcode = '1254851';
...
insert into taglink (id, product_id, tag_id) values (
  null /*autoinc id*/
  ,@product_id
  ,@tag_id );

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...