MySQL表拆分

时间:2012-02-23 12:54:00

标签: mysql sql

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

  1. 我想拆分大文本列,因为它不经常使用,可能会大大减少表格大小,从而提高性能。
  2. 我想将所有重复列“规范化”到一个单独的表(每个)中,以便我可以获取当前值列表,而无需在3M行上运行10 distinct个查询。这需要很长时间。
  3. #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 个答案:

答案 0 :(得分:1)

对于第1点,它是一对一的关系,因此您不需要外键(相反,您将对两个表使用相同的主键)。

  1. 使用相同类型的PK(当然不是自动增量),TEXT列创建表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
  4. 对于第2点,它有点长,但它在SQL中也是可行的(我以你的字段“Lookup”为例)。它可能是这样的:

    1. 使用自动增量ID和字段“title”创建辅助表“lookups”(如果您愿意,可以使用UNIQUE INDEX)。
    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