2014-04-02 1 views
0

Предположим, что у меня есть следующая таблица отношения родитель/ребенок в моей базе данных:Родитель/Детские столы Query Pattern

TABLE offer_master(offer_id int primary key, ..., scope varchar) TABLE offer_detail(offer_detail_id int primary key, offer_id int foreign key, customer_id int, ...)

где offer_master.scope может принимать значение

  • ИНДИВИДУАЛЬНЫЙ: когда предложение предназначено для конкретных клиентов. В этом случае всякий раз, когда строка вставлена ​​в offer_master, соответствующая строка равна , добавленной к offer_detail для каждого клиента, которому было предложено предложение.

например.

INSERT INTO offer_master(1, ..., 'INDIVIDUAL'); INSERT INTO offer_detail(offer_detail_id, offer_id, customer_id, ...) VALUES (1, 1, 100, ...) INSERT INTO offer_detail(offer_detail_id, offer_id, customer_id, ...) VALUES (2, 1, 101, ...)

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

INSERT INTO offer_master(2, ..., 'GLOBAL'); INSERT INTO offer_master(3, ..., 'GLOBAL');

но ребенок добавляется строка offer_detail только , когда клиент указывает определенный интерес к предложению. Так это может быть так, что в каком-то позже мы будем иметь

INSERT INTO offer_detail(offer_detail_id, offer_id, customer_id, ...) VALUES (4, 3, 100, ...)

Учитывая эту ситуацию, предположим, что мы хотели бы запросить базу данных , чтобы получить все предложения, которые были распространены на клиент 100; это включает в себя 3 вида предложений:

  • предложения, которые были расширены специально для клиента 100.
  • глобальные предложения, которые клиент 100 не проявляли никакого интереса к
  • глобальные предложения, которые клиент 100 сделал показать заинтересованность в

я вижу два подхода:..

  1. Использование подзапроса: SELECT * FROM offer_master WHERE offer_id in ( SELECT offer_id FROM offer_detail WHERE customer_id = 100) OR scope = 'GLOBAL'
  2. Использование UNION SELECT om.* FROM offer_master om INNER JOIN offer_detail od ON om.offer_id = od.offer_id WHERE od.customer_id = 100 UNION SELECT * FROM offer_master WHERE scope = 'GLOBAL' Примечание: a UNION ALL не может использоваться, поскольку глобальное предложение , которое клиент проявил интерес к нему, будет дублироваться.

Мой вопрос:

  1. есть ли этот шаблон запроса имя?
  2. Какой из двух методов запроса предпочтительнее?
  3. Должен ли быть усовершенствован проект базы данных?
+0

Использование одной таблицы для обозначения двух разных вещей - плохая идея. Ваш Offer_detail означает, что «предложение сделано конкретным клиентам» * и * «клиент указывает на некоторый интерес к предложению». Исправьте это первым. –

+0

Я думаю, что таблица Offer_detail в настоящее время представляет предложения, сделанные конкретным клиентам * или *, которые клиент указал на некоторый интерес к предложению. –

+1

Каждая строка в таблице должна иметь один и тот же предикат - такой же смысл. Это означает * один смысл, а не два. Если одна строка представляет сделанные предложения, а другая строка представляет интерес для клиентов, у вас есть проблема с дизайном. Исправьте это первым. –

ответ

1

Я не знаю названия шаблона.

Для меня второй запрос ясен, но я думаю, что все в порядке.

Представление_предложение представляет собой таблицу с двумя целями, которая для меня немного красная. У вас могут быть отдельные таблицы для клиентов в индивидуальном предложении и клиенты, которые выразили заинтересованность.

Смежные вопросы