Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Построение структуры базы данных 
:(
    Опции темы
korob2001
Дата 23.9.2015, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: нет
Всего: 61



Привет всем!

Дали задание написать интернет магазин для продажи электрических скутеров, запчастей для них, а так же различных аксессуаров (шлемы, перчатки и т.д). Первое, что пришло в голову, создать, старые - добрые таблички: products и categories. Уже даже почти всё сделал, но всё же сходил к заказчику для выяснения всех деталей, да бы добиться от него внятного ответа на вопрос: Чего он хочет?

В общем, такой вариант не прокатил, так как описание самого скутера должно быть максимально детализовано, т.е. нельзя всю информацию поместить в одно поле типа products.description, нужно сделать так, что бы всё, что касается скутера, хранилось в отдельных таблицах и/или полях. Тоже самое касается и запчастей, так как их поиск должен осуществляться не только по марке и/или модели скутера, а так же и по VIN номеру конкретного скутера.

Единственное, что пришло в голову, разбить все эти товары (скутеры, запчасти и аксессуары) на отдельные таблицы. Начал рисовать в Workbench ещё одну БД. Почти нарисовал, пока не дошёл до таблицы categories и врубился, что она мне теперь не слишком-то и нужна, потому как, по сути, у меня теперь каждая категория хранится в отдельной таблице (vehicles, parts, accessoires), так же возникли трудности с таблицей orders, фактически пришлось создавать для каждой из этих трёх таблиц, свою таблицу orders.

В общем меня постоянно не покидает чувство, что иду я куда-то, не туда. ;((((

PS: Я не прошу готовое решение, мне нужно просто указать направление. Если, что-то не понятно описал, дайте знать я опишу более подробно, просто не стал описывать изначально все таблицы их у меня получилось около 40-ка.


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
r00tGER
Дата 24.9.2015, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 20.5.2009
Где: Russia

Репутация: нет
Всего: нет



Цитата

   Укажите направление
   


Ок, только путь будет не близким (судя, по вашим действиям).
Берёте толстую книгу по реляционной алгебре, потом толстую книгу по СУБД.

Либо, надо избавиться от "чувство, что иду я куда-то, не туда" и продолжать,
как получается - этот пункт приведет либо к первому, либо к последнему.

Самый лучший вариант, если это задание было разовым и больше не будете проектировать БД - отдать его на выполнение тому, кто уже это делал.



Без обид, вовсе не хочу выпендреться. Но, когда задают такие вопросы в контексте реальной взрослой задачи - то хочется убедить, что надо сначала "прокачаться".


Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL WWW   Вверх
Akina
Дата 24.9.2015, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 453



В данном конкретном случае связь экземпляров сущностей "товар" является самым что ни на есть вульгарным деревом. Поскольку требуются такие операции с деревом, как выбор всей ветки экземпляров от родителя вниз по экземпляру и копирование ветки - лучше использовать именно tree-ориентированные структуры хранения данных, типа nested set. Хотя можно обойтись и вульгарным parent-child.
Поскольку отдельные экземпляры сущностей имеют множественные атрибуты и неоднородны, в части описания атрибутов экземпляра разумно посмотреть в сторону EAV. Хотя опять же можно обойтись и нормализованной сериализацией.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
korob2001
Дата 24.9.2015, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: нет
Всего: 61



Цитата(r00tGER @  24.9.2015,  05:49 Найти цитируемый пост)
Ок, только путь будет не близким (судя, по вашим действиям).Берёте толстую книгу по реляционной алгебре, потом толстую книгу по СУБД.

Я на близкий и не надеялся, мы не ищем лёгких путей. Что касается проф. книг, то их я уже читаю лет 15 нон-стоп, потому согласен с вами на все сто. Правда эту базу мне придётся создать до того, как я их прочитаю.

Цитата(r00tGER @  24.9.2015,  05:49 Найти цитируемый пост)
Самый лучший вариант, если это задание было разовым и больше не будете проектировать БД - отдать его на выполнение тому, кто уже это делал.

Раньше проектировал и буду ещё проектировать, потому что мне самому это интересно, да и нужно.
Ну а по большому счёту, я и здесь не могу с вами не согласиться, каждый должен заниматься своим делом. Донести бы это ещё и до моего шефа, а то он, ошибочно, полагает что программист - это дизайнер, верстальщик, БД архитектор, БД админ, а попутно ещё и должен администрировать и нести ответственность за состояние сети и всех устройств в ней, как виртуальных так и физических, ну и программист конечно же.
Я за последние 8 лет только и добился от него, что бы дизайнера хотя бы взяли, так что фотошопом и илюстратором я теперь не занимаюсь. Хотя книги всё равно продолжаю читать и по ним тоже.

Цитата(r00tGER @  24.9.2015,  05:49 Найти цитируемый пост)
Без обид, вовсе не хочу выпендреться. Но, когда задают такие вопросы в контексте реальной взрослой задачи - то хочется убедить, что надо сначала "прокачаться".

Да какие тут обиды? Вышел я уже из того, счастливого, возраста. Обижаться нужно на себя. Книги есть, даже в печатном виде, по тому же MySQL. Просто всё время откладывал на потом, вот оно и наступило - это "потом".

Цитата(Akina @  24.9.2015,  06:06 Найти цитируемый пост)
Поскольку отдельные экземпляры сущностей имеют множественные атрибуты и неоднородны, в части описания атрибутов экземпляра разумно посмотреть в сторону EAV

Я об этом тоже уже думал, только ведь придётся ещё и для каждого типа значений создавать отдельные таблицы, если я правильно понял значение EAV. Сегодня даже попробовал создал отдельную базу, с пятью таблицами. Запросы жуткие получались, так это я ещё значения хранил только в одной таблице, в поле типа TEXT.
Код

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

CREATE SCHEMA IF NOT EXISTS `eav_temp` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `eav_temp` ;

-- -----------------------------------------------------
-- Table `eav_temp`.`products`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `eav_temp`.`products` (
  `product_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(85) NOT NULL,
  `description` TEXT NOT NULL,
  PRIMARY KEY (`product_id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `eav_temp`.`categories`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `eav_temp`.`categories` (
  `category_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(85) NOT NULL,
  PRIMARY KEY (`category_id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `eav_temp`.`product_categories`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `eav_temp`.`product_categories` (
  `product_id` INT UNSIGNED NOT NULL,
  `category_id` INT UNSIGNED NOT NULL,
  PRIMARY KEY (`product_id`, `category_id`),
  INDEX `fk_product_categories_categories1_idx` (`category_id` ASC),
  CONSTRAINT `fk_product_categories_products`
    FOREIGN KEY (`product_id`)
    REFERENCES `eav_temp`.`products` (`product_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE,
  CONSTRAINT `fk_product_categories_categories1`
    FOREIGN KEY (`category_id`)
    REFERENCES `eav_temp`.`categories` (`category_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `eav_temp`.`product_attributes`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `eav_temp`.`product_attributes` (
  `attribute_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `product_id` INT UNSIGNED NOT NULL,
  `name` VARCHAR(85) NOT NULL,
  PRIMARY KEY (`attribute_id`),
  INDEX `fk_product_attributes_products1_idx` (`product_id` ASC),
  CONSTRAINT `fk_product_attributes_products1`
    FOREIGN KEY (`product_id`)
    REFERENCES `eav_temp`.`products` (`product_id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `eav_temp`.`attribute_values`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `eav_temp`.`attribute_values` (
  `attribute_id` BIGINT UNSIGNED NOT NULL,
  `product_id` INT UNSIGNED NOT NULL,
  `value` TEXT NOT NULL,
  INDEX `fk_attribute_values_product_attributes1_idx` (`attribute_id` ASC),
  INDEX `fk_attribute_values_products1_idx` (`product_id` ASC),
  CONSTRAINT `fk_attribute_values_product_attributes1`
    FOREIGN KEY (`attribute_id`)
    REFERENCES `eav_temp`.`product_attributes` (`attribute_id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `fk_attribute_values_products1`
    FOREIGN KEY (`product_id`)
    REFERENCES `eav_temp`.`products` (`product_id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

Хотя наверное нужно просто привыкнуть. Здесь запросы ещё были терпимые, но думаю если создам отдельные таблицы для всех типов значений, размер запросов увеличится в разы.

PS: Всем спасибо за помощь. Буду разбираться.

Это сообщение отредактировал(а) korob2001 - 25.9.2015, 08:19


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Akina
Дата 25.9.2015, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 453



Цитата(korob2001 @  25.9.2015,  00:26 Найти цитируемый пост)
придётся ещё и для каждого типа значений создавать отдельные таблицы, если я правильно понял значение EAV.

Вовсе необязательно. Можно обойтись и одной таблицей, в которой есть поля нескольких типов, причём заполняются только совместимые для данного значения, а остальные NULL.
А можно обойтись и одним текстовым - всё равно типизация в MySQL слабенькая, почти никакая, а неявное приведение возведено в ранг абсолюта.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
jsharp36
Дата 25.9.2015, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 8.10.2011

Репутация: нет
Всего: 1



Всё нормально, вы идете туда куда надо.

Вы в базе данных сейчас опытным путем нащупали, как реализовать то, что в ООП языках называется наследованием. В данном случае только данных.

Т.е. есть таблица, в которой обраны общие поля (базовый класс), и есть таблицы для конкретных типов товаров, которые расширяют базовый тип и имеют колонки, свойственные только этому типу.

Никаких EAV. Пока оно не нужно  и очень вредно. Вы всё правильно делаете.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
jsharp36
Дата 25.9.2015, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 8.10.2011

Репутация: нет
Всего: 1



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

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
korob2001
Дата 27.9.2015, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: нет
Всего: 61



Привет всем, ещё раз!

Цитата(jsharp36 @  25.9.2015,  06:15 Найти цитируемый пост)
Вы в базе данных сейчас опытным путем нащупали, как реализовать то, что в ООП языках называется наследованием. В данном случае только данных.

Мне почему-то кажется, что именно ООП и сеет во мне эти сомнения. Потому, как постоянно пытаюсь думать о том, как всё это дело будет выглядеть в ORM.

Цитата(Akina @  25.9.2015,  05:30 Найти цитируемый пост)
Вовсе необязательно. Можно обойтись и одной таблицей, в которой есть поля нескольких типов, причём заполняются только совместимые для данного значения, а остальные NULL.А можно обойтись и одним текстовым - всё равно типизация в MySQL слабенькая, почти никакая, а неявное приведение возведено в ранг абсолюта. 

Скорее всего так и сделаю, если не к чему другому так и не приду. TEXT поменяю на VARCHAR(32), этого будет вполне достаточно, что бы описать любое свойство модели. Там всё в основном числами описывается. Правда я не знаю как быть с внешними ключами. У меня сейчас например, поле models.battery_id связана с полем batteries.battery_id, где в таблице batteries описаны свойства батарейки. Или их тоже запихнуть в эту же таблицу?

Пришёл я пока к такой схеме. Не имеющие отношение к делу таблицы и поля, я не создавал. На BIGINT прошу не обращать внимание, это я погорячился.  smile 

user posted image

Сейчас кофе попью и попробую поюзать её запросами. Есть ещё одна идея, но я пока ещё не понял как её реализовать.



Это сообщение отредактировал(а) korob2001 - 28.9.2015, 00:41


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1310 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.