数据库分区 - 水平 vs 垂直 - 规范化和行拆分之间的区别?

54

我正在努力理解数据库分区的不同概念,以下是我的理解:

水平分区 / Sharding : 将一个表拆分为不同的表,每个表都包含最初表中的一部分行。例如: 将用户表按大陆进行拆分,如为北美洲创建一个子表,为欧洲创建另一个子表等。每个分区位于不同的物理位置(即不同的“机器”)。

就我所知,水平分区和Sharding 是完全相同的东西(?)。

垂直分区 : 我所了解到的(http://technet.microsoft.com/en-us/library/ms178148%28v=sql.105%29.aspx),有两种类型的垂直分区:

  • 规范化(从数据库中删除冗余数据的方法是通过拆分表并使用外键链接它们)。

  • 行拆分,这里是我不明白的地方:什么是规范化行拆分之间的区别?这两种技术有何不同?

我还在这篇文章中读到过(Difference between scaling horizontally and vertically for databases),水平分区和垂直分区的不同之处在于前者通过添加更多机器来扩展,而后者通过向现有机器添加更多功率(CPU、RAM)来扩展。这是正确的定义吗?我认为这两种技术之间的核心差异在于您拆分表的方式。

很抱歉我提出了这么多问题,但我有点困惑,因为我找到的许多不同网站都说不同的事情。

任何有助于澄清的帮助都将不胜感激。 任何带有几个表格的清晰简明演示链接也将非常有帮助。

3
好的,我会尽力为您提供准确和简洁的翻译。以下是需要翻译的内容:this question is more for http://dba.stackexchange.com/这个问题更适合在http://dba.stackexchange.com/上提问。 - Sam
4个回答

43

分区是一个相当通用的概念,可以应用于许多场景。当它考虑关系型数据的划分时,通常是指将表格进行行(水平)或列(垂直)分解。

垂直分区,也叫做行拆分,使用与数据库规范化相同的拆分技术,但通常称为(垂直/水平)数据分区,是一种物理优化,而规范化是在概念层面上进行的优化。

由于您要求进行简单演示 - 假设您有这样一个表:

create table data (
    id integer primary key, 
    status char(1) not null, 
    data1 varchar2(10) not null, 
    data2 varchar2(10) not null);

data 垂直地 划分的一种方法:按以下方式分割:

create table data_main (
    id integer primary key,
    status char(1) not null,
    data1 varchar2(10) not null );

create table data_rarely_used (
    id integer primary key,
    data2 varchar2(10) not null,
    foreign key (id) references data_main (id) );

例如,当您很少需要查询列数据2时,可以应用这种分区方法。分区data_main将占用更少的空间,因此全表扫描将更快,并且它更有可能适合DBMS的页面缓存。缺点是:当您必须查询data的所有列时,您显然必须加入表格,这比查询原始表格更昂贵。

请注意,您正在按照规范化表格的方式拆分列。但是,在这种情况下,data可能已经标准化为第三范式(甚至BCNF和4NF),但您决定进一步拆分它以进行物理优化。

使用Oracle语法对data进行水平分区的一种方法:

create table data (
    id integer primary key, 
    status char(1), 
    data1 varchar2(10), 
    data2 varchar2(10) )
    partition by list (status) ( 
       partition active_data values ( 'A' ),
       partition other_data values(default) 
    );

这将告诉DBMS在两个片段(就像两个表格)中内部存储data表,具体取决于status列的值。例如,当您通常只查询一个分区的行时,比如状态为"A"的行(我们称之为活动行),可以应用这种数据分区方式。与之前一样,全表扫描将更快(特别是如果只有少量活动行),活动行(和其他行)将连续存储(它们不会分散在与不同状态值的行共享的页面上,而且较可能活动行将位于页面缓存中。


34

水平分区在数据库中的应用

将所有字段保留下来,例如:表Employees有以下字段:

  • id,
  • name,
  • 地理位置,
  • email,
  • designation,
  • phone。

例如:1.保留所有字段并将记录分布在多个计算机中。例如在每台计算机上存储id= 1-100000 或 100000-200000 记录,并将其分布在多个计算机上。

例如:2.为各个地区保留单独的数据库,例如亚太地区和北美。

关键点:基于标准选择一组行

垂直分区在数据库中的应用

它与规范化类似,其中同一表被划分为多个表,并在需要时使用join进行连接。

例如,将idnamedesignation放在一个表中,
phoneemail则放在另一个表中,因为这些字段可能不经常被访问。

关键点:基于标准选择一组列。

  • 水平/垂直扩展与分区不同

水平扩展:

是关于添加更多的机器,以提高任何系统(包括数据库)的响应速度和可用性。其思想是将工作负载分配到多台计算机上。

垂直扩展:

是关于在现有机器或多台机器中添加更多CPU、内存等能力,以提高任何系统(包括数据库)的响应速度和可用性。在虚拟机设置中,可以进行虚拟配置,而无需添加实际物理机器。

Sameer Sukumaran


3
单一数据库的问题在于当它变得非常庞大时,所以需要对其进行分区,以减少搜索空间,使其能够更快地执行所需操作。有各种分区策略可用,例如:水平分区、垂直分区、基于哈希的分区、基于查找表的分区。与这些策略相比,水平和垂直扩展是不同的概念。
- 水平分区:它根据一些关键信息将给定的表/集合分成多个表/集合,这可以帮助获取正确的表,因为水平分区将在不同节点/机器上拥有多个表,例如:按地区划分的用户信息。 - 垂直分区:它将列分成多个部分,如上面的一个答案中提到的与用户信息、喜欢、评论、朋友等相关的列在社交网络应用程序中。 - 基于哈希的分区:它使用哈希函数来决定表/节点,并将关键元素作为输入生成哈希。如果我们改变表的数量,就需要重新排列数据,这是昂贵的。因此,在想要添加更多表/节点时会出现问题。 - 基于查找表的分区:它使用查找表来帮助根据给定的输入字段重定向到不同的表/节点。我们可以很容易地在此方法中添加新的表/节点。
水平扩展与垂直扩展:
当我们设计任何应用程序时,我们需要考虑扩展性。我们如何处理未来的大量流量?我们需要从内存消耗、延迟、CPU使用率、容错性、弹性等方面考虑。垂直扩展向单个计算机添加更多资源(例如:CPU、内存),以便它可以处理传入的流量。但是,这种方法存在限制,您无法添加超过某个限制的资源。水平扩展允许传入流量分布在多个节点上。它需要在前端具有负载均衡器,该负载均衡器基本上处理流量,并将流量导航到任何一个节点。水平扩展允许您添加足够数量的服务器,但您也需要这么多的节点。

1
Normalization和拆分的区别在于目的不同。
Normalization的主要目的是去除冗余数据,而行拆分的目的是分离不太需要的数据。
例如:假设您有一个名为All_Details的表,其中包含以下列 - id,Emp_name,Emp_address,Emp_phNo,Emp_other_data,Company_Name,Company_Address,Company_revenue。
现在,如果您想规范化表格,您将创建两个新表Employee_Details和Company_Details,并在Employee_Details表中保留company_id的外键。这样就可以删除冗余的公司数据。
现在让我们谈谈行拆分。假设即使在规范化之后,您仅访问employee_name和emp_phNo,但是您不经常访问emp_address和emp_other_data。因此,为了提高性能,您将Employee_Details表拆分为两个表。表1包含经常需要的数据(employee_name和emp_phNo),表2包含不经常需要的数据(Emp_address,Emp_other_data)。两个表都将具有相同的unique_key列,以便可以使用unique_key重新创建Employee_Details表的任何行。这可以大大提高系统性能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接