MySQL能否自动透明地重复删除字符串?

时间:2014-07-26 01:48:18

标签: mysql sql string

在C中,编译器分配"strings"个数字ID(4个字节的指针),并且只保留每个字符串的一个副本:对于char *a="Hello", *b="Hello";,只存储"Hello"的一个副本记忆。这对用户来说是完全自动且透明的。

我的问题是MySQL是否可以做同样的事情,即自动和透明地为用户重复删除字符串。

理想情况下,我希望它是数据库的内部存储机制,因此对于用户而言(如C的情况),数据库的外观和行为就像它包含实际字符串一样,而在实现中它会只包含指针。

在我的数据库中有许多重复的字符串,如下所示:

`unit`, `building`, `office`, `firstName`, `lastName`

Chicago main production unit    | headquarters | accounting | Jane | Smith
Chicago main production unit    | office       | sales      | Jane | Dow
Miami administrative department | headquarters | sales      | Mary | Smith
Miami administrative department | office       | accounting | Mary | Dow

等。其中'Miami administrative department''accounting''Smith'等字符串在不同记录中重复多次。

这增加了数据库的大小,因此我遇到了托管限制。

一个明显的解决方案是数据规范化:为名称维护一个单独的表

`id`, `string`

1 | Chicago main production unit
2 | Miami administrative department
3 | headquarters
4 | accounting
5 | Jane
6 | Smith
7 | office
8 | sales
9 | Dow

然后将我的表格作为

`unit_id`, `building_id`, `office_id`, `firstName_id`, `lastName_id`

1 | 3 | 4 | 5 | 6
1 | 7 | 8 | 5 | 9

并在输入和输出上翻译所有字符串。但当然这非常麻烦。

我的问题是MySQL是否可以为用户自动且透明地执行:每当我插入一行时,它会自动更新字符串表并仅在表中存储id而不是字符串,对于DELETE,WHERE也是如此等等,这样对于用户来说,表格看起来就像它有字符串一样,但占用的空间更少。

1 个答案:

答案 0 :(得分:1)

  

我的问题是MySQL是否可以这样做。

虽然你当然可以实现所需的结果(它被称为数据规范化),但MySQL并没有隐式地做到这一点。

  

MySQL能否为用户自动且透明地做到这一点?

不,MySQL不能自动为你做 - 你必须自己做。您需要在查询和DDL语句中明确说明它。

这是一个简短的演示,展示如何创建查找表,然后在插入中使用它并选择:

create table lookup(id int, name varchar(10));
create table data(id int, id_lookup int);
insert into lookup(id,name) values (1,'quick');
insert into lookup(id,name) values (2,'brown');
insert into lookup(id,name) values (3,'fox');

insert into data (id, id_lookup)
values (110, (select id from lookup where name = 'quick'));
insert into data (id, id_lookup)
values (120, (select id from lookup where name = 'brown'));
insert into data (id, id_lookup)
values (130, (select id from lookup where name = 'quick'));
insert into data (id, id_lookup)
values (140, (select id from lookup where name = 'fox'));

现在data包含以下行:

110 1
120 2
130 1
140 3

要选择名称,您需要加入lookup表:

select d.id, t.name
from data d
join lookup t on t.id=d.id_lookup

Demo on sqlfiddle.

注意:为所有字符串创建查找表并不常见。通常,您可以为每种字符串创建单独的查找表(例如unit_lookupbuilding_lookup等),或者使用特殊的查找代码列对查找表进行分区:

id code name
-- ---- ----
 1 unit Chicago
 2 unit Miami
 3 bldg Headquarters
 4 bldg Office