Sql server 重复数据还是性能更好?
我们需要用不同的语言显示我们的产品名称,但只有一些产品名称的语言和英语不同。当我们使用特定语言查询产品时,如果缺少特定语言名称,我们希望以英语显示默认名称 为了获得更好的查询性能,当缺少特定语言的名称时,我们必须将默认的英文名称填入依赖于语言的产品名称表(languageid+productid是主键)。它在这个依赖于语言的表中产生了大量重复的名称,当默认的英文名称更改时,更新这个表有点困难 目前,我们有大约300000个产品,约30种语言,此表中有超过8000000行,至少90%以上的数据是重复的,并使用默认的英文名称填充。但是如果我们在查询中使用leftjoin和isnull检查,查询性能会慢得多 谁能向我推荐一种更好的数据库设计,以避免重复数据的填充,并具有更好的查询性能 当前表架构如下所示Sql server 重复数据还是性能更好?,sql-server,database-design,Sql Server,Database Design,我们需要用不同的语言显示我们的产品名称,但只有一些产品名称的语言和英语不同。当我们使用特定语言查询产品时,如果缺少特定语言名称,我们希望以英语显示默认名称 为了获得更好的查询性能,当缺少特定语言的名称时,我们必须将默认的英文名称填入依赖于语言的产品名称表(languageid+productid是主键)。它在这个依赖于语言的表中产生了大量重复的名称,当默认的英文名称更改时,更新这个表有点困难 目前,我们有大约300000个产品,约30种语言,此表中有超过8000000行,至少90%以上的数据是重
Table1 (about 300,000 rows)
ProductId | Country | Currency | others fields
------------|----------------|-----------|---------------
Product A | US | USD | ...
Product B | GB | GBP | ...
Table2 (about 9,000,000 rows)
LanguageId | ProductId | Product Name
------------|----------------|--------------------------
English | Product A | Product A Name
English | Product B | Product B Name
German | Product A | Produkt A Name
German | Product B | Product B Name (it's filled by English name)
我曾尝试在下面的查询中避免重复数据,但性能有点差
SELECT
A.ProductId,
A.Country,
ISNULL(B1.ProductName, B2.ProductName) as ProductName
FROM
Table1 A (NOLOCK)
LEFT JOIN Table2 B1 (NOLOCK) on A.ProductId = B1.ProductId
LEFT JOIN Table2 B2 (NOLOCK) on A.ProductId = B2.ProductId and B2.LanguageId = 'ENGLISH'
WHERE
B1.LanguageId = 'German'
ORDER BY
ISNULL(B1.ProductName, B2.ProductName)
我不确定这对于您的特定情况是否可行,但为什么不让UI接口层或应用程序层通过通用本地化模式处理翻译呢?我不确定这对于您的特定情况是否可行,但是为什么不让UI界面层或应用程序层通过通用本地化模式处理翻译呢?如果该语言记录中没有产品名称,请在该字段中输入一个
NULL
。执行查询时,请使用COALESCE
将NULL
替换为您的英文产品名称
SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
我提议的设计如下:
Language | ProductName | TitleMenu
----------------------------------
English | Widgetizer | Title
French | La Widgette | La Title
Spanish | | El Title
由于西班牙语有一个
NULL
条目,因此COALESCE
跳过NULL并输入默认产品名称。如果该语言记录中没有产品名称,请在该字段中输入NULL
。执行查询时,请使用COALESCE
将NULL
替换为您的英文产品名称
SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
我提议的设计如下:
Language | ProductName | TitleMenu
----------------------------------
English | Widgetizer | Title
French | La Widgette | La Title
Spanish | | El Title
由于西班牙语有一个
NULL
条目,因此COALESCE
跳过NULL并输入默认产品名称。您测试过左连接和ISNULL了吗?还是这只是猜测?考虑到您正在转换大量数据,我想说可选语言行会快得多,除非您有一些非常糟糕的索引
SELECT COALESCE(l.ProductName, 'Product Name')
FROM Language l
SELECT
...,
ISNULL(L.languageproductName, P.productname)
FROM
Product P
LEFT JOIN
LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage
你测试过左连接和ISNULL了吗?还是这只是猜测?考虑到您正在转换大量数据,我想说可选语言行会快得多,除非您有一些非常糟糕的索引
SELECT
...,
ISNULL(L.languageproductName, P.productname)
FROM
Product P
LEFT JOIN
LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage
你能把当前的表模式放在你的帖子里吗?你能把当前的表模式放在你的帖子里吗?所以你建议了两列并保留了重复的英文名称?所以你建议了两列并保留了重复的英文名称?我在我的查询中尝试了左连接和ISNULL。因为我们还需要按产品名称对数据进行排序。速度要慢得多。我在查询中尝试了左连接和ISNULL。因为我们还需要按产品名称对数据进行排序。速度要慢得多。在UI层进行本地化很困难,因为我们还需要按产品名称字段进行排序。@CodeRhino,值得关注的问题。但是,在应用层中仍然可能进行本地化?当我只想在页面中显示指定的产品时,在应用层中处理本地化很容易。但是,当我想搜索和分页超过300000个产品并按产品名称显示结果和排序时,该如何处理呢?在UI层进行本地化很难,因为我们还需要按产品名称字段排序。@CodeRhino,值得关注的问题。但是,在应用层中仍然可能进行本地化?当我只想在页面中显示指定的产品时,在应用层中处理本地化很容易。但是,当我想搜索和分页超过300000个产品并显示结果和按产品名称排序时,我应该如何处理呢。