如何在数据库中存储语言标记ID,如smallint或varchar?

时间:2009-08-20 15:45:48

标签: database database-design performance

我想知道如何存储语言标签ID(例如en-US)。

一个简单的例子:

Table l10n ( l10n_id SMALLINT, code VARCHAR(5) )  
    PK: l10n_id
    Index on code  
Table product ( product_id INT, ..language-neutral columns.. )  
    PK: product_id
Table product_l10n ( product_id INT, l10n_id SMALLINT, ..language-specific columns.. )  
    PK: product_id, l10n_id.  
    Indexes on product_id and l10n_id

如果我们使用varchar ID:

Table l10n ( l10n_id VARCHAR(5) )  
    PK: l10n_id

1。使用smallint ID:

需要与语言表进行连接:

    SELECT *
    FROM product a
        LEFT JOIN product_l10n b ON b.id = a.id
        LEFT JOIN l10n c ON c.id = b.id
    WHERE c.code = 'en-US';

2。使用varchar ID:

我们不必在查询中使用l10n表:

    SELECT *
    FROM product a
        LEFT JOIN product_l10n b ON (b.product_id = a.id AND b.l10n_id = 'en-US');

smallint占用2个字节,而varchar(5)占用6个字节(在PostgreSQL中,请参阅doc)。
所以我猜所有索引(l10n pk,product_l10n pk和product_l10n.l10n_id)都会因varchar ID而变大。因此,表现会下降。这是对的吗?

第3。结论

我是否正确地说我们拥有的本地化数据越多,使用varchar ID的性能就越低? 因此,使用smallint ID是一种更好的设计。

1 个答案:

答案 0 :(得分:1)

存储VARCHARs时,整理会发挥作用,使索引比较效率降低(至少在MySQL中)。

另外,在MySQLVARCHAR的关键失误比关键命中要贵得多。

在我的博客中查看此文章的性能:

另一方面,将代码存储在单独的表中将需要额外的JOIN,这会消除所有性能优势。

所以在MySQL中,将代码保留为TINYINT可能是值得的,而在其他系统中,最好将代码保留为VARCHAR