我正在寻找能够正确存档非常大的表格的解决方案(每天大约10,000行)。
我目前有这种情况:
订单表:
CREATE TABLE `tbl_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idproduct` int(11) NOT NULL DEFAULT '0',
`iduser` int(11) NOT NULL DEFAULT '0',
`state` int(11) NOT NULL DEFAULT '0',
`progressive` int(11) NOT NULL DEFAULT '0',
`show-voucher` int(11) NOT NULL DEFAULT '0',
`voucher-custom` int(11) NOT NULL DEFAULT '0',
`check-validate` int(11) NOT NULL DEFAULT '0',
`code-order` varchar(8) NOT NULL DEFAULT '',
`code-product` char(15) NOT NULL DEFAULT '',
`product-year` int(11) NOT NULL DEFAULT '2017',
`product-area` char(3) NOT NULL DEFAULT '',
`payment-type` char(3) NOT NULL DEFAULT '',
`usr-qnt` int(11) NOT NULL DEFAULT '0',
`usr-id` char(11) NOT NULL DEFAULT '',
`usr-cid` char(8) NOT NULL DEFAULT '',
`usr-ct` char(3) NOT NULL DEFAULT '000',
`price` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-penale` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-rate` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-contanti` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-bonusmalus-rate` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-bonusmalus-contanti` decimal(10,2) NOT NULL DEFAULT '0.00',
`price-incasso-contanti` decimal(10,2) NOT NULL DEFAULT '0.00',
`rate-qnt` int(11) NOT NULL DEFAULT '0',
`card-qnt` int(11) NOT NULL DEFAULT '0',
`grp-user` longtext NOT NULL,
`grp-price` longtext NOT NULL,
`grp-item` longtext NOT NULL,
`grp-element` longtext NOT NULL,
`bonusmalus-description` varchar(500) NOT NULL,
`note-s` text NOT NULL ,
`note-c` text NOT NULL,
`note-incasso` text NOT NULL,
`note-interne` text NOT NULL,
`d-start` date NOT NULL DEFAULT '0000-00-00',
`d-end` date NOT NULL DEFAULT '0000-00-00',
`d-create` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-incasso` date NOT NULL DEFAULT '0000-00-00',
`d-sconf` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-cconf` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-export` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-expire` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-notify-vote` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`d-lastupdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `iduser` (`iduser`),
KEY `code-order` (`code-order`),
KEY `code-product` (`code-product`),
KEY `idproduct` (`idproduct`),
KEY `state` (`state`),
KEY `price` (`price`),
KEY `usr-qnt` (`usr-qnt`),
KEY `d-expire` (`d-expire`),
KEY `d-export` (`d-export`),
KEY `price-bonusmalus-contanti` (`price-bonusmalus-contanti`),
KEY `price-penale` (`price-penale`),
KEY `price-bonusmalus-contanti_2` (`price-bonusmalus-contanti`),
KEY `price-rate` (`price-rate`),
KEY `price-contanti` (`price-contanti`),
KEY `show-voucher` (`show-voucher`),
KEY `voucher-custom` (`voucher-custom`),
KEY `check-validate` (`check-validate`),
KEY `progressive` (`progressive`),
KEY `d-incasso` (`d-incasso`),
KEY `price-incasso-contanti` (`price-incasso-contanti`),
KEY `d-notify-vote` (`d-notify-vote`),
KEY `product-year` (`product-year`),
KEY `product-area` (`product-area`),
KEY `d-lastupdate` (`d-lastupdate`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
订单是用户( iduser )为旅游套餐提出的请求,例如 Booking.com
此表每天生成 8,000 到 15,000 行。 我担心这张桌子会变得太大而导致问题。
我的核心领域是:
我已经在网上阅读了几个解决方案,但我无法弄清楚哪一个可能是最好的解决方案:
1)将主表划分为许多其他子表或许多其他数据库?
实施例
或
或
或
在这种情况下,是通过UNION进行SELECT吗?
2)对表格进行分区? 哪些字段可以执行? 产品年份?产品面积(共20个)? 订单创建日期(d-create)? 按id?
3)Sharding?但我不知道它是什么......
4)Innodb o MyISAM?
我仍然可以采用的一个解决方案是将LONGTEXT字段拆分为辅助表以减少tbl_order的权重:
怀疑:如果我这样做,我减轻了tbl_order表的权重,但我没有减少记录数量。因此,必须对 db.tbl_order-grp-user,db.tbl_order-grp-price,db.tbl_order-grp-item,db.tbl_order-grp-elements 表进行分区?如果你使用范围idorder?
包含所有数据的SELECT将为:
Select *,
( SELECT `u`.`data` FROM `db`.`tbl_order-grp-user` as `u` where `u`.`idorder`=`order`.`id`) as `grp-user`,
( SELECT `p`.`data` FROM `db`.`tbl_order-grp-price` as `p` where `p`.`idorder`=`order`.`id`) as `grp-price`,
( SELECT `i`.`data` FROM `db`.`tbl_order-grp-item` as `i` where `i`.`idorder`=`order`.`id`) as `grp-item`
FROM `db`.`tbl_order` as `order`
WHERE ............
感谢所有支持! : - )
答案 0 :(得分:1)
新手警报......
当INT
(3个字节)就足够时,不要使用MEDIUMINT UNSIGNED
(4个字节)。查看剩余的INT
选项。
不要盲目索引每一列。
请查看您的SELECTs
,了解哪些复合索引是有益的。查看我的Index Cookbook。
不要太担心15K /天 - 小于1 /秒。 100 /秒是潜在问题的第一个转折点。
不要PARTITION
。它不是不是的万能药,通常不会带来任何好处。用例很少。
不要拆分成多个“相同”的表格。永远。 (嗯,有用的用例非常少。)
不要害怕一百万行;确实关心了十亿行。
不要将CHAR
用于可变长度字段;使用VARCHAR
。
请考虑使用utf8mb4而不是utf8。 utf8mb4匹配外部世界UTF-8
的视图,包括表情符号和所有中文。
使用InnoDB。期。完全停止。 MyISAM正在消失; InnoDB在几乎所有方面都是好的或者更好。
考虑更改列名以避免-
; _
很常见,当您忘记背景时会避免错误。
不要碎片。 (这是跨多个服务器分割数据。)这是一个中等大小的表,中等流量;需要对具有大量流量的大型桌子进行分片。
在适当的地方说CHARACTER SET ascii
。例如product-area
。你现在拥有9个字节 - 3个字符*每个字符3个字节(utf8)的空间。
考虑TINYINT(3) UNSIGNED ZEROFILL
product-area
- 这将花费1个字节并为您重建前导零。
考虑您是否拥有“自然”PRIMARY KEY
而不是AUTO_INCREMENT
。
请告诉我们grp
列包含的内容。
请回到暂定的SELECT
陈述。没有他们,我无法完成这次审查。
请考虑这是否应该是单个表格。真的是一个用户只订购一种产品吗?您可能需要一个用户表,一个产品表,一个订单表等等。