2014-07-18 62 views
0

我已经研究过这个问题。我不是唯一一个提出这个问题的人......但是我希望你对最佳做法有所想法。与类别和子类别相关的数据库设计

我试图设计一个数据库,将跟踪金融交易。为了简单起见,每笔交易只能有一个类别,每个类别只能有一个子类别。

我有一个自引用表,就像这样:

Table: Categories 
ID, int, primary key 
parentID, int, foreign key 
description, text 

长话短说,你最终得到这样的数据:

1 Auto [null] 
2 Bills [null] 
3 Healthcare [null] 
4 Maintenance 1 
5 Gasoline 1 
6 Cell Phone 2 
7 Rent 2 
8 Prescriptions 3 
9 Dentist 3 

到目前为止,一切都很好。 这里是我的问题

我不知道我应该涉及所有这一切回到我的交易表的正确方法。 'Transactions'有一个'Category'和'Subcategory'的列。 Transaction.ID将是PK,而Categories.ID将是FK。

随着上述规定的方式,这意味着从分类的任何值可以被写入类别或子类别相关的分类交易...

这是我的责任,程序员通过控制访问表形成?换句话说,我唯一的选择是“以编程方式控制”进入“类别”和“子类别”列的内容。

请记住,每个类别只能有一个子类别。选择的类别应该只允许该类别的孩子...

我有道理吗?

GOOD:汽车 - 维护 BAD:医疗保健 - 汽油

+0

...为什么你只能有一个子类?这是否意味着像“汽油 - 汽油”这样的东西会被禁止?或者你的意思是你只想要一个嵌套层次? 'Transactions'应该只有一列 - 'category',它可能包含一个子类别。或者,或者定义一个多列外键。你如何预测加载数据?该程序/过程有责任首先不加载不良数据,因此请将所需的任何基本保护放在那里。 –

+0

你的意思是说每个子类别只能有一个类别? –

+0

目前,我并不太在意层次结构的深度......每个子类别可能只有一个父级。这部分很简单...我的问题是限制写入交易表的内容。例如:如果我使用“自动”填充Transactions.Category,那么当我到达Transaction.SubCategory时,我应该只能选择自动的孩子。 – raydlevel5

回答

0

所以你的类别是否不是正交的,独立的(如性别和城市),而是等级(如州和县)。

为了强制执行分级分类,请使用ID列为主键的单个分类表(在数据表中引用为外键)以及两个描述性字段Category和Subcategory。

为了便于数据输入,您可以提供一个组合框类别,用于过滤可用的子类别。然而,实际的外键引用是由在子类别组合框中进行的选择提供的,该组合框必须列出两个字段,分类和子类别。通常将这两个字段与分隔符(如短划线( - )或管道(|))连接起来。

+0

单个FK子类别就足够了。子类别表可以具有FK引用类别。因此,与汽油相关的所有交易都与汽车间接相关。 –

+0

@WalterMitty:这是以子类别*描述*始终是唯一的。考虑州和县的例子;在美国的50个州中有很多重复的县名,因此只有在与州描述相结合的情况下才能确保任何特定的县名。 –

+0

它假定子类别具有身份。没有身份的实体是一个问题,即使其他事情都是正确的。 –

1

您提出的情况是关系表中编码分层数据树结构的更一般问题的子集。自从关系数据库在20世纪70年代后期首次提出这个案例以来,这个案例就已经被详细研究了。

特别是在簿记系统中,每一次都会出现子类别和类别的概念。较大规模的工业系统倾向于具有四级系统,总体账户类型(费用),类别(运输),子类别(汽车)和子子类别(汽油)。

如果您使用以下搜索词:“关系设计中的树结构”,则可能会提高您的研究的效率。该搜索产生以下维基百科摘要:

http://en.wikipedia.org/wiki/Hierarchical_database_model

你可以找到很多相关的问题和答案在这里SO。在“嵌套集”或“邻接列表”下搜索几种技术。

你的问题是要简化你将找到的答案,只有两个级别:类别和子类别。

我认为你选择的任何设计都希望明确下列规则:子类别决定类别。而IMO则希望DBMS强制执行此规则,以避免事务以与其类别不一致的子类别结束。

+0

我认为我们处于同一页面! Transactions.SubCategory必须与Categories.Table中的正确父对齐。编码是我的责任,还是我可以通过关系强制执行? 我似乎无法建立适当的关系....迄今为止我所做的最好的事情是分别为Transactions.Categories和Transactions.SubCategories显示ALL Categories和SubCategories。换句话说,我还没有找到一种方法来限制基于Transaction.Category的Transaction.Subcategories。 – raydlevel5

+0

在子类别/类别关系中强化一致性基本上是数据规范化的问题。规范化的设计将只存储一次这种关系。看看规范化的设计。至于数据输入表单如何向用户提供选项,这是表单设计而不是数据库设计的问题。 –