在我的数据库设计中使用高级冗余非规范化数据来提高性能.我经常会存储通常需要加入或计算的数据.例如,如果我有一个User表和一个Task表,我会在每个Task记录中冗余地存储Username和UserDisplayName.另一个例子是存储聚合,例如将TaskCount存储在User表中.
这非常适合性能,因为应用程序具有比插入,更新或删除操作更多的读取,并且因为某些值(如用户名)很少更改.然而,最大的缺点是必须通过应用程序代码或触发器强制执行完整性.更新可能会非常麻烦.
我的问题是这可以在SQL Server 2005/2010中自动完成...也许通过持久/永久视图.有人会推荐另一种可能的解决方案或技术 我听说基于文档的数据库(如CouchDB和MongoDB)可以更有效地处理非规范化数据.
当您使用非规范化架构时,传播更新的最佳方法是什么?是否应该在同一个功能中完成?
我有这样的架构:
var Authors = new Schema({
...
name: {type: String, required:true},
period: {type: Schema.Types.ObjectId, ref:'Periods'},
quotes: [{type: Schema.Types.ObjectId, ref: 'Quotes'}]
active: Boolean,
...
})
Run Code Online (Sandbox Code Playgroud)
然后:
var Periods = new Schema({
...
name: {type: String, required:true},
authors: [{type: Schema.Types.ObjectId, ref:'Authors'}],
active: Boolean,
...
})
Run Code Online (Sandbox Code Playgroud)
现在说我想对作者进行非规范化,因为该period字段将始终只使用句点的名称(这是唯一的,不能有两个具有相同名称的句点).然后说我将我的模式转换为:
var Authors = new Schema({
...
name: {type: String, required:true},
period: String, //no longer a ref
active: Boolean,
...
})
Run Code Online (Sandbox Code Playgroud)
现在,Mongoose不再知道period字段连接到Period模式.因此,当一个句点的名称发生变化时,我可以更新该字段.我创建了一个服务模块,提供如下界面:
exports.updatePeriod = function(id, changes) {...}
Run Code Online (Sandbox Code Playgroud)
在此函数中,我将完成更改以更新需要更新的期间文档.所以这是我的问题.那么,我应该更新此方法中的所有作者吗?因为那时该方法必须知道Author模式和使用period的任何其他模式,从而在这些实体之间创建大量耦合.有没有更好的办法?
也许我可以发出一个事件,一段时间已经更新,所有具有非规范化周期参考的模式都可以观察到它,这是一个更好的解决方案吗?我不太确定如何解决这个问题.
对于像stackoverflow这样的高流量网站,数据库设计和规范化的最佳实践是什么?
是否应该使用标准化数据库进行记录保存或标准化技术或两者的组合?
将规范化数据库设计为记录保存的主数据库以减少冗余并同时维护数据库的另一种非规范化形式以便快速搜索是否合理?
要么
主数据库是否应该非规范化,但在应用程序级别使用标准化视图来进行快速数据库操作?
或其他一些方法?
performance database-design high-availability denormalization database-normalization
我已经开始了一个新项目,他们有一个非常规范化的数据库.可以查找的所有内容都作为外键存储到查找表中.这是规范化和精细的,但我最终为最简单的查询做了5个表连接.
from va in VehicleActions
join vat in VehicleActionTypes on va.VehicleActionTypeId equals vat.VehicleActionTypeId
join ai in ActivityInvolvements on va.VehicleActionId equals ai.VehicleActionId
join a in Agencies on va.AgencyId equals a.AgencyId
join vd in VehicleDescriptions on ai.VehicleDescriptionId equals vd.VehicleDescriptionId
join s in States on vd.LicensePlateStateId equals s.StateId
where va.CreatedDate > DateTime.Now.AddHours(-DateTime.Now.Hour)
select new {va.VehicleActionId,a.AgencyCode,vat.Description,vat.Code,
vd.LicensePlateNumber,LPNState = s.Code,va.LatestDateTime,va.CreatedDate}
Run Code Online (Sandbox Code Playgroud)
我想建议我们取消一些东西.喜欢州代码.在我的一生中,我没有看到州代码的变化.类似的故事与3个字母的代理商代码.这些由代理机构发放,永远不会改变.
当我找到状态代码问题和5表连接的DBA时.我得到了"我们正常化"和"加入很快"的回应.
反规范化有一个令人信服的论据吗?如果没别的话,我会为了理智而这样做.
T-SQL中的相同查询:
SELECT VehicleAction.VehicleActionID
, Agency.AgencyCode AS ActionAgency
, VehicleActionType.Description
, VehicleDescription.LicensePlateNumber
, State.Code AS LPNState
, VehicleAction.LatestDateTime AS ActionLatestDateTime
, VehicleAction.CreatedDate
FROM …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用MongoDB,C#和NoRM来处理一些示例项目,但是在这一点上,我在围绕数据模型时遇到了困难.使用RDBMS的相关数据是没有问题的.然而,在MongoDB中,我很难决定如何处理它们.
让我们以StackOverflow为例......我可以理解问题页面上的大部分数据都应该包含在一个文档中.标题,问题文本,修订,评论......在一个文档对象中都很好.
我开始变得模糊的问题是用户数据,例如用户名,头像,声誉(特别经常变化)...每次用户更改时,您是否会对数千个文档记录进行非规范化更新或以某种方式链接数据在一起?
在不导致每次页面加载时发生大量查询的情况下,实现用户关系的最有效方法是什么?我注意到DbReference<T>NoRM中的类型,但还没有找到一种很好的方法来使用它.如果我有可空的可选关系怎么办?
感谢您的见解!
假设我们有这些表格:
CREATE TABLE A (
id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE B (
id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE Parent (
id SERIAL NOT NULL PRIMARY KEY,
aId INTEGER NOT NULL REFERENCES A (id),
bId INTEGER NOT NULL REFERENCES B (id),
UNIQUE(aId, bId)
);
CREATE TABLE Child (
parentId INTEGER NOT NULL REFERENCES Parent (id),
createdOn TIMESTAMP NOT NULL
);
是否可以创建一个唯一约束,Child使得对于Child最多一个引用中的所有行,Parent具有某个值aId?换句话说,我可以创建一个唯一约束,以便上表的连接没有重复aId吗?我在想 - 我能找到的每个数据库的语法似乎都与每个约束的一个表相关联 - …
sql postgresql relational-algebra normalization denormalization
作为这个问题的必然结果,我想知道是否有好的比较研究我可以参考并传递使用RDMBS的优点做连接优化与系统非规范化,以便始终一次访问一个表.
具体来说,我想要的信息:
有一段历史可以看到我要去的地方:我们的系统使用内部数据库抽象层,但它很老,无法处理多个表.因此,必须在每个相关表上使用多个查询来实例化所有复杂对象.现在为了确保系统始终使用单个表格,在整个表格中使用重度系统非规范化,有时会将两个或三个层次压平.至于nn关系,他们似乎已经通过精心设计他们的数据模型来解决这个问题,以避免这种关系,并始终回到1-n或n-1.
最终结果是一个复杂的过于复杂的系统,客户经常抱怨性能.在分析这样的瓶颈时,他们永远不会质疑系统所基于的这些基本前提,并且总是寻找其他解决方案.
我错过了什么 ?我认为整个想法是错误的,但不知何故缺乏无可辩驳的证据来证明(或反驳)它,这就是我转向你的集体智慧,指向我的良好,被广泛接受的文学,可以说服我团队中的其他人方法是错误的(说服我,我对于一致的数据模型我太偏执和教条).
我的下一步是建立自己的测试平台并收集结果,因为我讨厌重新发明轮子我想知道这个主题已经有了什么.
----编辑注意:系统最初是使用没有数据库系统的平面文件构建的...后来才将其移植到数据库,因为客户端坚持使用Oracle进行系统管理.他们没有重构,只是简单地添加了对现有系统的关系数据库的支持.平面文件支持后来被删除,但我们仍在等待重构利用数据库.
我目前有3个表格,用于存储世界上所有主要城市的信息,每个地区/州对应这些国家/地区,以及每个城市/地区.
现在我在我的数据库中有大约6个其他表,例如需要完全相同的5列的用户或组织表:地址,郊区,城市,州/地区,国家.所以我想知道是否"良好"的规范化实践可能使用存储这5条信息的"位置"表,然后用户或组织表将有一个location_id来引用回来.

好主意还是坏主意?我也在考虑使用"联系人"表,其原理相同,包括home_phone,business_phone,mobile_phone,email_address,而不是在6个表中的每个表中都有相同的5列.
任何建议表示赞赏 非常感谢!
mysql database database-design normalization denormalization
所以我理解如何创建外键,我知道FK的目的是什么.但是我在理解如何使用它们时遇到了问题.我问了一个关于外键的问题HERE(点击链接)
这是我做的:
CREATE TABLE user(
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE items(
i_id INT(11) NOT NULL AUTO_INCREMENT,
name TINYTEXT NOT NULL,
price DECIMAL(8,2) NOT NULL,
PRIMARY KEY (i_id)
);
CREATE TABLE user_purchase(
i_id INT(11) NOT NULL,
name TINYTEXT NOT NULL,
id INT(11) NOT NULL,
FOREIGN KEY (i_id) REFERENCES items(i_id),
FOREIGN KEY (name) REFERENCES items(name),
FOREIGN KEY (id) REFERENCES user(id)
);
Run Code Online (Sandbox Code Playgroud)
现在我的问题是如何使用PHP充分利用它?从上面的链接,人们建议在user_purchase表中只使用一个外键是好的,但如果我想要多个列呢?为什么我们不为同一个表的不同列使用多个外键?
我正在使用mysql和php.如果你能展示一些如何使用带有外键的表来使用PHP来获取使用MYSQL命令获取信息的例子,我将不胜感激.我真的需要一个彻底的解释.
我还需要理解规范化和非规范化这两个术语.如果您能够通过示例详细解释这些术语,或者如果您对数据库设计,实现等初学者的一些好书有任何建议,我将不胜感激,我将非常感激.
非常感谢.
我正在研究CQRS / ES体系结构。我们将多个异步投影并行运行到读取存储中,因为某些投影可能比其他投影慢得多,并且我们希望与写入端保持更多同步,以实现更快的投影。
我正在尝试了解有关如何生成读取模型以及可能需要进行多少数据重复的方法。
让我们以带有物料的订单作为简化示例。一个订单可以有多个项目,每个项目都有一个名称。项目和订单是单独的汇总。
我可以尝试以更规范的方式保存读取的模型,在该模型中,我为每个项目创建实体或文档并订购,然后对其进行引用-或者我可能想以更规范化的方式在有订单的情况下保存它其中包含项目。
归一化
{
Id: Order1,
Items: [Item1, Item2]
}
{
Id: Item1,
Name: "Foosaver 9000"
}
{
Id: Item2,
Name: "Foosaver 7500"
}
Run Code Online (Sandbox Code Playgroud)
使用更规范的格式将允许单个投影处理影响/影响物品和订单的事件并更新相应的对象。这也意味着项目名称的任何更改都会影响所有订单。例如,客户可能会收到与相应发票不同的其他物品的交货单(显然,该模型可能不够好,并导致我们面临与非规范化相同的问题...)
非正规化
{
Id: Order1,
Items: [
{Id: Item1, Name: "Foosaver 9000"},
{Id: Item2, Name: "Foosaver 7500"},
]
}
Run Code Online (Sandbox Code Playgroud)
但是,反规范化将需要一些可以在其中查找当前相关数据的源(例如项目)。这意味着我要么必须传输事件中可能需要的所有信息,要么必须跟踪为非规范化而获取的数据。这也意味着我可能需要为每个投影执行一次操作(即,我可能需要一个非规范化的ItemForOrder以及一个非规范化的ItemForSomethingElse),它们都只包含每个非规范化实体或文档所需的最基本的属性(无论它们是什么时候)创建或修改)。
如果我要在读取存储中共享相同的物料,则最终可能会从不同的时间点混合物料定义,因为物料和订单的预测可能不会以相同的速度运行。在最坏的情况下,项目的投影可能尚未创建我需要为其属性来源的项目。
通常,在处理事件流中的关系时我有什么方法?
更新2016-06-17
目前,我正在通过针对每个非规范化读取模型及其相关数据运行单个投影来解决此问题。如果我有多个必须共享相同相关数据的读取模型,那么我可能会将它们放在同一投影中,以避免重复查找所需的相同相关数据。
这些相关的模型甚至可能已被标准化,优化,但是我必须访问它们。我的投影是唯一读取和写入它们的东西,因此我确切地知道如何读取它们。
// related data
public class Item
{
public Guid Id {get; set;}
public string Name {get; set;}
/* and whatever else …Run Code Online (Sandbox Code Playgroud) denormalization ×10
sql ×3
database ×2
mongodb ×2
mysql ×2
c# ×1
cqrs ×1
legacy-code ×1
mongoose ×1
node.js ×1
norm ×1
normalize ×1
performance ×1
postgresql ×1
projection ×1
sql-server ×1