Разработка базы данных для хранения списков - PullRequest
0 голосов
/ 04 июня 2018

Прошу прощения за неоднозначность имен столбцов и таблиц.В моей базе данных есть две таблицы A и B. Между этими таблицами существует много-много взаимосвязей.

Таблица A содержит около 200 записей

Table A structure
Id.   Definition
12    Def1
42    Def2 .... etc. 

Таблица B содержит около5 миллиардов записей

Column 1 .   Associated Id(from table A)
eg . abc      12
     abc      21
     pqr      42

Я пытаюсь оптимизировать способ хранения данных в таблице B, поскольку в них много избыточных данных.Структура, о которой я думаю, выглядит следующим образом:

Column 1        Associated Ids
abc             12, 21
pqr             42

Столбец «Связанный идентификатор» может иметь обновления при добавлении новых строк в таблицу A.

Это хорошая структура для создания вэтот сценарий?Если да, каким должен быть тип столбца для «Связанного идентификатора»?Я использую базу данных mysql.

Создание табличных операторов.

CREATE TABLE `A` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `creat_usr_id` varchar(20) NOT NULL,
  `creat_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `modfd_usr_id` varchar(20) DEFAULT NULL,
  `modfd_ts` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `A_ak1` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=277 DEFAULT CHARSET=utf8;

CREATE TABLE `B`(
  `col1` varchar(128) NOT NULL,
  `id` int(11) NOT NULL,
  `added_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `creat_usr_id` varchar(20) NOT NULL,
  `creat_ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`col1`,`id`,`added_dt`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(added_dt))
(PARTITION Lessthan_2016 VALUES LESS THAN (1451606400) ENGINE = InnoDB,
 PARTITION L`Ω`essthan_201603 VALUES LESS THAN (1456790400) ENGINE = InnoDB,
 PARTITION Lessthan_201605 VALUES LESS THAN (1462060800) ENGINE = InnoDB,
 PARTITION Lessthan_201607 VALUES LESS THAN (1467331200) ENGINE = InnoDB,
 PARTITION Lessthan_201609 VALUES LESS THAN (1472688000) ENGINE = InnoDB,
 PARTITION Lessthan_201611 VALUES LESS THAN (1477958400) ENGINE = InnoDB,
 PARTITION Lessthan_201701 VALUES LESS THAN (1483228800) ENGINE = InnoDB,
 PARTITION pfuture VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;

Индексы.

  Table Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Index_type  Comment Index_comment
    B          0        PRIMARY         1             col1        A        
 2             NULL       NULL      BTREE       
    B          0        PRIMARY         2              id         A        
 6             NULL       NULL      BTREE       
    B          0         PRIMARY        3             added_dt    A        
 6             NULL       NULL      BTREE       

1 Ответ

0 голосов
/ 05 июня 2018

5 миллиардов строк здесь.Позвольте мне пройтись по вещам:

  • col1 varchar (128) NOT NULL,

Как часто повторяется этот столбец?То есть, стоит ли его «нормализовать»?

  • id int (11) NOT NULL,

Сократить размер этого столбца пополам (4байт -> 2), поскольку у вас есть только 200 различных идентификаторов:

a_id SMALLINT UNSIGNED NOT NULL

Диапазон значений: 0..65535

  • added_dt отметка времени NOT NULL DEFAULT CURRENT_TIMESTAMP,

Пожалуйста, объясните, почему это часть PK.Это довольно странная вещь.

  • creat_usr_id varchar (20) NOT NULL,
  • creat_ts отметка времени NOT NULL DEFAULT CURRENT_TIMESTAMP,

Бросьте их как беспорядок, если только вы не можете оправдать отслеживание 5 миллиардов действий таким образом.

  • ПЕРВИЧНЫЙ КЛЮЧ (col1, id, added_dt)

Бьюсь об заклад, вы в конечном итоге получите две строки в одну секунду.ПК является «уникальным».Возможно, вам нужен только (col, a_id) `?Иначе, вы разрешаете добавлять пару col-a_id несколько раз.Или, может быть, вы хотите, чтобы IODKU добавил новую строку вместо обновления временной метки?

  • PARTITION ...

Это полезно, если (и, вероятно, только если) вы собираетесьудалить «старые» строки.Еще, пожалуйста, объясните, почему вы выбрали разбиение.

Сложно просмотреть схему, не увидев основной SELECTs.В случае больших таблиц мы также должны рассмотреть INSERTs, UPDATEs и DELETEs, поскольку каждая из них может создавать серьезные проблемы с производительностью.

При 100 вставках строк в секунду это будетзаймет больше года, чтобы добавить 5B строк.Как быстро появятся ряды?Это также может быть серьезной проблемой производительности.

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