以下是我的表结构
表1:
CREATE TABLE page_visits
(
domain varchar(50) NOT NULL,
campaign_id BIGINT DEFAULT NULL,
subscriber_id BIGINT DEFAULT NULL
);
上表的示例行。
+-----------+------------------+------------------+
| domain | subscriber_id | campaign_id |
+-----------+------------------+------------------+
| abcdef | 5834234569635200 | 5814789314123456 |
| abcdef | 5834979786543520 | 5814789314123456 |
| abcdef | 1238003995770880 | 5814789314123456 |
| abcdef | 4567900658540544 | 5814789314123456 |
| abcdef | 8765906092156928 | 5814789314123456 |
+--------+------------------+---------------------+
我们有1亿行(大约),大小为100 GB(大约)。我想规范化这个表。而不是" varchar"域的数据类型,我想在上表中使用domain_id作为中型int。因为域名在此表中重复很多次。
我会将域保存在单独的表中,如下所示,域名在下表中将是唯一的。
表2:
CREATE TABLE domains
(
domain_id MEDIUMINT UNSIGNED NOT NULL,
domain_name varchar(50) NOT NULL
);
问题:对于表1的每个读写请求,我需要调用表2从域名获取domain_id,因为我没有在app中存储domain_id。无论如何要优化这个以减小尺寸??
答案 0 :(得分:0)
table page_vits create statement:
CREATE TABLE `page_visits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domain_id` int(11) DEFAULT NULL,
`campaign_id` bigint(20) DEFAULT NULL,
`subscriber_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `domain_id_idx` (`domain_id`),
CONSTRAINT `domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`domain_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
现在domain_id引用了您的域表。
表域创建语句:
CREATE TABLE `domains` (
`domain_id` int(11) NOT NULL AUTO_INCREMENT,
`domain_name` varchar(50) NOT NULL,
PRIMARY KEY (`domain_id`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1;
ER图
答案 1 :(得分:0)
这是一个理想的问题,您可以在性能和规范化之间进行权衡。 在具体情况下,您可以执行以下操作:
where
子句中)以执行任何选择查询时,还有一个额外的性能优势,因为它们需要CPU时间较短。domains
表以遵循规范化,请根据适当的条件对page_visits
表进行分区,以便您执行的选择始终从单个分区中获取数据。
阅读MySQL partitioning limitations。 domain_id
表中的page_visits
列以更快地获取行。 [根据您的不同问题陈述,这当然会很棘手,如果需要可能需要更改]。