SQL大表优化

时间:2012-01-05 16:05:50

标签: mysql sql database database-design relational-database

我目前正在开发一个可以操作大量数据的大型应用程序。 我正在设计数据模型,我想知道如何针对大量数据调整此模型。 (我的DBMS是MySQL)

我有一个包含名为“values”的对象的表。有6列名为:

  • ID
  • type_bool
  • type_float
  • type_date
  • TYPE_TEXT
  • type_int

根据该值的类型(在别处写入),其中一列具有数据,其他列为NULL值。

此表旨在包含数百万行(增长速度非常快)。它也会被阅读很多次。

我的设计会用很少的数据制作很多行。我想知道制作5个不同的表是否更好,每个表只包含一种类型的数据。有了这个解决方案,就会有更多的联合。

你能给我一些建议吗? 非常感谢你!

编辑:我的表格描述

表元素 在应用程序中,有些元素包含属性。

  • 会有很多行。
  • 有很多读/写,很少更新/删除。

TABLE ATTRIBUTEDEFINITION 在表attributeDefinition中描述了每个属性(设计时),告诉该属性的类型。

  • 不会有很多行
  • 开头很少写,但很多读。

TABLE ATTRIBUTEVALUE 之后,另一个表“attributeValue”包含每个元素的每个attributeDefinition的实际数据。

  • 会有很多行([nb of Element] x [nb of attribute])
  • 很多读/写/更新

TABLE LISTVALUE *某些类型很复杂,例如list_type。可用于此类型的值集在另一个名为LISTVALUE的表中。然后,属性值表包含一个id,它是ListValue Table *

的一个键

以下是创建语句

 CREATE TABLE `element` (
   `id` int(11),
   `group` int(11), ...



 CREATE TABLE `attributeDefinition` (
   `id` int(11) ,
   `name` varchar(100) ,
   `typeChamps` varchar(45) 

 CREATE TABLE `attributeValue` (
   `id` int(11) ,
   `elementId` int(11) , ===> table element
   `attributeDefinitionId` int(11) , ===> table attributeDefinition
   `type_bool` tinyint(1) ,
   `type_float` decimal(9,8) ,
   `type_int` int(11) ,
   `type_text` varchar(1000) ,
   `type_date` date,
   `type_list` int(11) , ===> table listValue



 CREATE TABLE `listValue` (
   `id` int(11) ,
   `name` varchar(100), ...

还有一个SELECT示例,它检索id为66的组的所有元素:

SELECT elementId, 
       attributeValue.id as idAttribute, 
       attributeDefinition.name as attributeName, 
       attributeDefinition.typeChamps as attributeType, 
       listValue.name as valeurDeListe, 
       attributeValue.type_bool,
       attributeValue.type_int,
       DATE_FORMAT(vdc.type_date, '%d/%m/%Y') as type_date,
       attributeValue.type_float,
       attributeValue.type_text
FROM element
JOIN attributeValue ON attributeValue.elementId = element.id
JOIN attributeDefinition ON attributeValue.attributeDefinitionId = attributeDefinition.id
LEFT JOIN listValue ON attributeValue.type_list = listValue.id
WHERE `e`.`group` = '66'

在我的应用程序中,foreach行,我打印与属性类型对应的值。

5 个答案:

答案 0 :(得分:3)

由于每次只插入一个列,因此为每种数据类型创建一个不同的表 - 如果要插入大量数据,则会因此设计浪费大量空间。

每个表中的行数较少会增加索引查找速度。

您的列名称应描述其中的数据,而不是列类型。

阅读Database Normalisation

答案 1 :(得分:1)

写作不会成为问题。阅读将

你必须问自己:

  • 您多久会查询一次?

  • 是旧数据修改还是只是“追加”?

==>如果答案经常/仅附加,或者对旧数据进行微小修改,缓存可能会解决您的阅读问题,因为您不会经常查询基础。

答案 2 :(得分:0)

每行会有很多空字段。如果表格不大,但正如您所说的那样,将有数百万行,因此您浪费空间并且查询将花费更长的时间来执行。做这样的事情: 表格1 id |型

表2 类型|其他领域

答案 3 :(得分:0)

我有建议,虽然它可能不是你想要的那种:-)
这看起来像entity-attribute-value架构;使用这种模式会导致所有类型的维护/性能噩梦:

  • 复杂查询以获取主记录的所有值(实质上,您必须将结果表连接N次以获取主记录的N个属性)
  • 没有引用完整性(我假设您将使用单独的主数据表查找值;您不能使用外键约束)
  • 浪费磁盘空间(因为你的桌子将被稀疏地填充)

有关避免此类架构的更完整原因列表,我建议您获取SQL Antipatterns的副本

答案 4 :(得分:0)

最后,我尝试实施这两种解决方案,然后我将它们推向了一边。 对于这两种解决方案,都有一个表元素和一个表属性定义如下:

<强> [attributeDefinition]

| id | group   | name                        | type       | 
| 12 | 51      | 'The Bool attribute'        | type_bool  | 
| 12 | 51      | 'The Int  attribute'        | type_int   | 
| 12 | 51      | 'The first Float attribute' | type_float | 
| 12 | 51      | 'The second Float attribute'| type_float | 

<强> [元素]

| id | group   | name                        
| 42 | 51      | 'An element in the group 51'

第一个解决方案(最佳解决方案)

一个大表,每个类型有一列,有许多空单元格。每个元素的每个属性的每个值。

<强> [的AttributeValue]

| id | element | attributeDefinition | type_int | type_bool | type_float | ...
| 1  | 42      | 12                  | NULL     | TRUE      | NULL       | NULL...
| 2  | 42      | 13                  | 5421     | NULL      | NULL       | NULL...
| 3  | 42      | 14                  | NULL     | NULL      | 23.5       | NULL...
| 4  | 42      | 15                  | NULL     | NULL      | 56.8       | NULL...

一个用于attributeDefinition的表,用于描述组中每个元素的每个属性。


第二种解决方案(更糟糕的是)

8个表,每种类型一个:

<强> [type_float]

| id | group   | element | value |
| 3  | 51      | 42      | 23.5  |
| 4  | 51      | 42      | 56.8  |

<强> [type_bool]

| id | group   | element | value |
| 1  | 51      | 42      | TRUE  |

<强> [type_int]

| id | group   | element | value |
| 2  | 51      | 42      | 5421  |

结论

我的工作台首先查看数据库大小。我在大表中有1 500 000行,如果有10种数据类型,则每个小表中大约有150 000行。 查看phpMyAdmin,大小几乎完全相同。

  1. 第一个结论:没有空单元格。
  2. 在那之后,我的第二个工作台是性能测试,将所有元素的所有属性的所有值都放在一个组中。数据库中有15个组。每个小组都有:

    • 400个元素
    • 每个元素30个属性

    因此,每个表[type_ *]中的[attributeValue] 1200行中有12 000行。 First SELECT仅在[attributeValue]和[element]之间进行一次连接,以便在组中放置WHERE。

    第二个SELECT在每个表[type _ *]中使用带有10个SELECT的UNION。

    第二个SELECT是10倍!

    1. 第二个结论:一个表比许多表好。