2012-02-23 139 views
0

我有一张约20列的表格。其中10个通常倾向于有15个左右的值中的1个(每列不同)。另外,一列有一个较大的字符串。该表目前有超过300万行,并在不断增长。它大约是1GB大(只是数据)MySQL表格拆分

  1. 我想拆分大文本列,因为它不经常使用,并可能会大大减少表大小,从而提高性能。
  2. 我想将所有那些重复的列“归一化”到一个单独的表格(每个表格)中,以便我可以在不对3M行执行10 distinct查询的情况下获取当前值的列表。这需要很长时间。

#2将是一对多关系。 #1可以是1对1或1对多。我不在乎。

问题是:这些可以通过纯SQL语句完成吗?怎么样?或者,我是否需要编写一个程序将数据放入新表中,并获取PK并将其插入右侧一列中的一列?

编辑
这里是什么,我试图做一个样本:

ID Field1 Lookup Text 
10 val1 look1 some very long text 
11 val2 look2 more very long text 
12 val2 look1 NULL 
13 val4 look1 some very long text 
. 
. 
. 

要这样:

ID Field1 Lookup Text 
10 val1 1  1 
11 val2 2  2 
12 val2 1  0 
13 val4 1  4 (1?) 
. 
. 
. 

回答

1

对于点1,它是一个对一关系,所以你不需要外键(相反,你将对这两个表使用相同的主键)。

  1. 与同类型(不当然自动递增),你的文字列的PK创建表mytable_text,并且,如果你使用的是InnoDB(在这种情况下,建议)的外键你的第一张(主)桌子。您可以将ON DELETE CASCADE添加到外键以简化维护。
  2. INSERT INTO mytable_text (id, large_text_column) (SELECT id, large_text_column FROM mytable)
  3. ALTER TABLE mytable DROP large_text_column

对于第2点,这是一个有点长,但它也是可行的SQL(我是在你的领域的“查找”的例子)。这可能是类似的东西:

  1. 创建辅助表“查找”与自动增量ID和场“称号”,例如(具有唯一索引,如果你喜欢它的感觉)。
  2. INSERT INTO lookups (title) (SELECT DISTINCT Lookup FROM mytable)
  3. SET foreign_key_checks = 0
  4. ALTER TABLE mytable ADD lookup_id INTEGER UNSIGNED [...], ADD FOREIGN KEY [...]
  5. UPDATE mytable SET lookup_id = (SELECT id FROM lookups WHERE lookup.title = mytable.Lookup
  6. ALTER TABLE mytable DROP Lookup
  7. (可选)ALTER TABLE mytable CHANGE lookup_id Lookup [...](如果你想保持相同的名称)
  8. SET foreign_key_checks = 1
+0

我添加了一个例子 – baruch 2012-02-23 13:28:01

+0

我根据你的例子编辑了我的答案。请注意,对于3M行,alter语句可能需要一些时间。 – rlanvin 2012-02-23 13:43:25