我对MySql有简短的经验,对规范化和非规范化技术没有多少经验
我们正在使用Google Analytics产品。对于我们的每个客户,我们提供一个JavaScript代码,他们将其放在他们的网站上。如果用户访问我们的客户站点,则java脚本代码会点击我们的服务器,以便我们代表此客户存储此页面访问。每个客户都包含唯一的域名,这意味着客户由域
确定我们将此页面访问存储在MySql表中。
以下是表格架构。
CREATE TABLE page_visits2 (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
domain varchar(50) DEFAULT NULL,
guid varbinary(16) DEFAULT NULL,
sid varbinary(16) DEFAULT NULL,
url varchar(2500) DEFAULT NULL,
ip binary(16) DEFAULT NULL,
is_new tinyint(1) DEFAULT NULL,
ref varchar(2500) DEFAULT NULL,
user_agent varchar(255) DEFAULT NULL,
stats_time datetime DEFAULT NULL,
country char(2) DEFAULT NULL, (ISO 3166-1 alpha-2)
region char(5) DEFAULT NULL, (ISO-3166-2)
city varchar(50) DEFAULT NULL,
city_lat_long varchar(50) DEFAULT NULL,
email varchar(100) DEFAULT NULL,
PRIMARY KEY (id),
KEY id (id)
)
MySql服务器详细信息
这是Google云MySql(版本为5.6),存储容量为10TB。
截至目前,我们的表格中有3.5亿行,表格大小为300 GB。
所以表大小很大,甚至索引大小也很大(大约70 GB。我会在单独的问题中询问索引)。
我们所有的读/写查询都取决于特定的域。我们不会针对多个域进行查询。因此 所有queires中必须使用domain ='domain_name' 。 Domian名称不会改变。
我想从此表中删除冗余数据,并希望减小表大小,以便我可以将整个索引放在内存中。同时我也想要更好的查询性能。由于规范化,我不想放松查询性能。我们需要规范化才能获得更好的查询性能。
我的方法很多
在上表中使用domain_id而不是domain列。我将单独创建域名表(domain_name,domain_id)
在上表中的地址相关字段中使用address_id。我将创建地址表并存储所有地址字段。 (addresss_id,国家,城市,地区,city_long_lat)
但我不知道如何准确实施上述方法。请告诉上述方法是否正确以及任何其他更好的想法?
我的主要疑问是我是否为域创建单独的表,例如在查询
之后select count(*) from page_visits where domain ='abc';
我不知道域名的domain_id有'abc'所以我必须调用第一个域表来获取domain_id然后需要调用实际查询。就像地址表一样我也需要调用地址表来获取address_id和实际查询。
这意味着对于每个读/写查询,我正在进行两次调用。我在这里犯了什么错误吗?