Jump to content

MySql!!Связь многие ко многим через связующую таблицу + 1 таблица


Recommended Posts

У меня такая задача:

 

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

Имеется так же таблица с элитными номерами не привязанных к какому-либо тарифу.

 

У некоторых тарифов есть возможность подключить данный тариф к элитному номеру, за что может взиматься дополнительная плата за подключение к тарифу элитного номера.

В таблице тарифов, создал два столбца для отношений с таблицей элитных номеров:

1 столбец number с типом ENUM('0','1'), где 1 будет значить,что тариф можно подключить к элитному номеру.

2 столбец number_price будет содержать цену подключения элитного номера к тарифу.

 

Модель таблиц https://yadi.sk/i/UQbRHKkte4wPs

 

SQL:

 

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';
-- -----------------------------------------------------
-- Schema number
-- ----------------------------------------------------
-- -----------------------------------------------------
-- Schema number
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `number` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `number` ;
-- -----------------------------------------------------
-- Table `number`.`number`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `number`.`number` (
 `id_number` INT UNSIGNED NOT NULL AUTO_INCREMENT,
 `number` VARCHAR(12) NOT NULL,
 `price` INT(7) UNSIGNED NOT NULL,
 `id_operator` SMALLINT(2) NOT NULL,
 `delete` ENUM('0','1') NOT NULL DEFAULT '1',
 PRIMARY KEY (`id_number`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `number`.`tariffs`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `number`.`tariffs` (
 `id_tarif` INT UNSIGNED NOT NULL AUTO_INCREMENT,
 `text` TEXT NOT NULL,
 `title` VARCHAR(255) NULL,
 `desc` VARCHAR(255) NULL,
 `img` VARCHAR(100) NULL,
 `id_operator` SMALLINT(2) UNSIGNED NOT NULL,
 `id_category` SMALLINT(3) UNSIGNED NOT NULL,
 `visitors` MEDIUMINT(6) NOT NULL DEFAULT 0,
 `recommended` ENUM('0','1') NULL DEFAULT 0,
 `visible` ENUM('0','1') NULL DEFAULT 0,
 `price` MEDIUMINT(6) UNSIGNED NOT NULL,
 `translit_title` VARCHAR(255) NOT NULL,
 `number` ENUM('0','1') NOT NULL DEFAULT 0,
 `delete` ENUM('0','1') NOT NULL DEFAULT '1',
 `number_price` SMALLINT(5) NOT NULL DEFAULT 0,
 PRIMARY KEY (`id_tarif`),
 FULLTEXT INDEX `itext` (`text` ASC))
ENGINE = MyISAM
PACK_KEYS = DEFAULT;

-- -----------------------------------------------------
-- Table `number`.`numbers_for_tariffs`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `number`.`numbers_for_tariffs` (
 `id_num_tarif` INT NOT NULL AUTO_INCREMENT,
 `number` VARCHAR(12) NOT NULL,
 `price` INT(6) NOT NULL,
 PRIMARY KEY (`id_num_tarif`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `number`.`numbers_for_tariffs_has_tariffs`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `number`.`numbers_for_tariffs_has_tariffs` (
 `id_num_tarif` INT NOT NULL,
 `id_tarif` INT UNSIGNED NOT NULL,
 PRIMARY KEY (`id_num_tarif`, `id_tarif`),
 INDEX `fk_tarif_idx` (`id_tarif` ASC),
 INDEX `fk_numbers_for_tariffs_idx` (`id_num_tarif` ASC),
 CONSTRAINT `fk_numbers_for_tariffs1`
   FOREIGN KEY (`id_num_tarif`)
   REFERENCES `number`.`numbers_for_tariffs` (`id_num_tarif`)
   ON DELETE CASCADE
   ON UPDATE CASCADE,
 CONSTRAINT `fk_tarif_tarif1`
   FOREIGN KEY (`id_tarif`)
   REFERENCES `number`.`tariffs` (`id_tarif`)
   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;

 

 

 

Так вот, как мне лучше реализовать отношения между этими таблицами?

Link to comment
Share on other sites

DAGpro, слишком много сущностей...

numbers_for_tariffs - не нужна.

numbers_for_tariffs_has_tariffs - не нужна.

 

Так тариф к номеру или номер к тарифу?

Может быть поле "элитности" перенесёшь в таблицу number, в виде "rating enum('1', '2', '3')" - not null не нужен, пусть будет незаданным для простых номеров.

Свяжи number c tariffs через таблицу links с полями:

id int auto_increment primary

id_number

id_tariff

составной индекс на id_number и id_tariff не забудь.

Link to comment
Share on other sites

RNZ, Номер к тарифу.(не очень понимаю этот момент).

 

Есть корпоративные безлимитные тарифы, с привязанными к ним номера(простые,средние,элитные).

Номера привязаны к одному тарифу,но можно переключить к другому тарифу из одной корпоративной группы,если такие тарифы есть(поэтому связь многие ко многим.).

 

Так же есть элитные номера для физ.лиц.

К некоторым тарифам можно подключить номера для физ.лиц.

Вот ссылка на сайт http://nomera05.ru , думаю это даст лучше понимания к тому что я написал .

 

поле "элитности" было не для разделения таблиц простые с элитными. А для определения,что данному тарифу можно подключить элитные номера для физ.лиц.

 

Таблица links это та же таблица numbers_for_tariffs_has_tariffs с нюансами и другим названием.

А вот какие столбцы использовать в связующей таблице я еще подумаю.

На тостере был вопрос насчет какой вариант лучше выбрать для связующей таблицы http://toster.ru/q/83506.

Так что я еще просмотрю какой вариант из таблиц выбрать мой добавив составной primary индекс на оба столбца или твой с primary id.

Link to comment
Share on other sites

DAGpro, стоит избегать таких названий:

numbers_for_tariffs

numbers_for_tariffs_has_tariffs.

потому и предложил links.

 

 

Номер к тарифу.(не очень понимаю этот момент).

На самом деле я-бы изменил логику "к номеру всё остальное" ("один-ко-многим"). В логике "многие-ко-многим" - нет надобности, т.к. номеру может быть назначен активным только один тариф.

И раз есть "корпоративные группы" в которых может быть несколько тарифов, то лучше ввести таблицу с группами:

groups:

id

name

 

 

Добавить в tariffs и number поле group_id.

Добавить в number поле tariff_id.

Т.о. на основании group_id можно будет определять список доступных для номера тарифов, а поле number.tariff_id связать с tariffs.id_taiff.

 

 

И ещё момент по семантике именования:

number.id вместо number.id_number

tariff.id вместо tariffs.id_tariff

group.id вместо groups.id_group

link вместо links (не нужна если будешь вести group, ну или можно оставить для ведения истории, правда тогда лучше завести history и вести в ней log изменений на основании history.number_id)

 

 

тогда как:

number.group_id

number.tariff_id

tariff.group_id

 

 

Семантика .group_id, tariff_id в том, что сразу видна связь из названия поля в виде table.linkedtable_column

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...