목차
PARTY
PARTY_ROLE
PARTY_RELATIONSHIP
PARTY_RELATIONSHIP_TYPE
PARTY_CLASSIFICATION_TYPE
PARTY_CLASSIFICATION_GROUP
PARTY_CLASSIFICATION
CONTENT_MECH
CONTENT_MECH_TYPE
PARTY_CONTACT_MECH
CONTACT_MECH_PURPOSE_TYPE
PARTY_CONTACT_MECH_PURPOSE
CONTENT_TYPE
CONTENT
PARTY_CONTENT_TYPE
总结
更高的抽象级别
数据库表的继承关系
时效性设计
데이터 베이스 MySQL 튜토리얼 谈ApacheOFbiz会员模块表结构设计

谈ApacheOFbiz会员模块表结构设计

Jun 07, 2016 pm 04:12 PM
회원 데이터 베이스 기준 치수 구조 설계

数据库表的结构设计可谓是ofbiz除技术框架之外,另一个非常值得学习的方向。这篇文章我们来谈谈ofbiz对电子商务会员表的设计。 PARTY ofbiz对人、团体进行了抽象,称之为party,翻译为中文称之为“会员”(但我觉得抛开领域,如果你也有相关的设计需求,在其

数据库表的结构设计可谓是ofbiz除技术框架之外,另一个非常值得学习的方向。这篇文章我们来谈谈ofbiz对电子商务会员表的设计。

PARTY

ofbiz对人、团体进行了抽象,称之为party,翻译为中文称之为“会员”(但我觉得抛开领域,如果你也有相关的设计需求,在其他领域可能称之为团体更合适)。会员在ofbiz被设计为一个抽象的概念(对应到面向对象设计中,你可以称其为一个基类),它有两个具体的延伸(继承者):分别是PERSON以及PARTY_GROUP。数据库的E-R图:

\

这里PERSON,PARTY_GROUP分别表示“个人会员”、“组织会员”。Party只是一种抽象,它定义了可以被抽象为“会员”的对象所具有的基本特征。但 “个人”以及“组织”会员却具备比 “基本会员”更多的特征,所以此处从Party延伸出两张表来存储这些额外的特征信息它们的主键都是PARTY表的PARTY_ID。
喎?http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD48aDE+UEFSVFlfVFlQRTwvaDE+PHA+cGFydHlUeXBltqjS5cHLcGFydHm1xMDg0M3UvMr4oaNFLVLNvMjnz8KjujxiciAvJmd0OzwvcD48cD48aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20141208/2014120809092365.png" alt="\" />

可以看到,PARTY_TYPE是拥有层级关系的(它的一个属性PARENT_TYPE_ID自关联了PARTY_TYPE的主键:PARTY_TYPE_ID,下面如果看到E-R图上有自关联到本身的,都表示这种关系,不再敖述)。

ofbiz提供的初始数据中有如下几种party type:

\

构建成层级关系如下图所示:

\

上面展示的两张表:PERSON、PARTY_GROUP也是其中的两个partyType,并且这些partyType都可以独立扩展的,PERSON、PARTY_GROUP也是仅有的两个扩展。这也是上面表结构中这两个记录的HAS_TABLE值为Y的原因。

PARTY_ROLE

就跟社会的“角色分工”一样,一个会员在系统中也必定会拥有属于自己的角色。而PARTY_ROLE表就是用于关联会员与角色类型的关系表,很明显会员与角色类型是多对多的关系(这里需要提及的是:ofbiz中只有角色类型,没有角色,或者更准确点说,角色类型包含了角色)。

\

PARTY_RELATIONSHIP

上面我们看到的会员是一类“抽象”的实体。不管它表示的是个人,还是组织,它总是会跟其他会员发生关系,就好像一个人不可能脱离社会而孤立得存在着,他必然有自己的社会角色,并跟社会的其他“团体”产生联系。这在ofbiz中被抽象为“partyRelationship”。我们来看它是如果表达“关系”这个语义的:

\

当你把这些所有的字段连起来,它几乎能涵盖所有的“会员关系”(要知道,有时会员关系会非常复杂,一个会员有时会存在于多个系统中)。

我们再回过头来,看PARTY_RELATIONSHIP的表结构设计:

\

可以看到前五个键形成了联合主键,其中前四个都是形如XXX_FROM,XXX_TO的ID标识。表示从“FROM”方往“TO”方建立关系。其中PARTY_ID_FROM与ROLE_TYPE_ID_FROM是“源”方;PARTY_ID_TO与ROLE_TYPE_ID_TO是“目标”方。

从上面图中也可以看到,每个关系都带有两个DATETIME字段,分别表示:开始日期,截止日期。这说明关系是有“时段”这个属性的。当然,如果没有截止日期,可以看做是“永久”的。因此为了防止关系过了生效时段无法再次建立关系(因为主键不允许重复),所以选择了联合“FROM_DATE”作为联合主键(后面如果再次建立相同的关系时,只要FROM_DATE不一样,就视为一条新记录)。

这里有必要说明一下,在ofbiz的数据库设计中,大量采用了“时段”这个属性来标识记录的有效性。这样的设计与逻辑删除相比的好处是:它除了减少了删除时因为外键约束等连带关系导致的错误,还可以直接充当“历史记录”的作用,省去了对历史表的维护,当然它的缺点就是:表中的记录会比其他的设计多得多。

当然,From跟To只是为了标识两者建立了关系,却并未说明它们到底存在怎样的关系,就好像——我跟你是朋友。这句话可以拆分为三部分:FROM方:我,TO方:你,关系是:朋友。上表中用一个字段表示了关系:PARTY_RELATIONSHIP_TYPE_ID(这只是一个外键,关联着表PARTY_RELATIONSHIP_TYPE)。

在界面上新建一个关系(此处是从外部到自己的一个关系):

\

PARTY_RELATIONSHIP_TYPE

该表约束了关系的类型。比如:雇佣者、朋友、父、子、管理者,E-R图:

\

从图中可以看出,会员关系类型也拥有层次关系。表中还有两个特别的字段:

ROLE_TYPE_ID_VALID_FROMROLE_TYPE_ID_VALID_TO
它们用于约束这个关系的建立双方的角色。也就是说,不是任意的两个角色之间一定可以建立起某个特定的会员关系。当然这两个字段通常都为空,表示不对此加以限制。
对每个关系类型,都可以扩展以独立实现关系(被扩展后关系类型记录的字段HAS_TABLE被标识为Y,否则默认为N),在ofbiz的初始化数据中,唯一被扩展的关系类型是:EMPLOYMENT。我们来看看EMPLOYMENT关系表的实现:
\
可以看到,它跟之前的PARTY_RELATIONSHIP的主键实现方式一样。因此可以把它看做是:PARTY_RELATIONSHIP_TYPE_ID为EMPLOYMENT的PARTY_RELATIONSHIP的特殊实现。
在界面上建立一个关系类型:
\

PARTY_CLASSIFICATION_TYPE

为了便于管理,ofbiz对会员按各种维度进行分类,常见的分类的类型有:年收入、价值等级、产业、雇员数量等;

PARTY_CLASSIFICATION_GROUP

会员并不会直接跟分类的类型产生关系,而是跟一个或多个分类组产生关联关系。而分类组受分类类型约束。
新建一个分类组:
\

PARTY_CLASSIFICATION

会员的分类相关表的关系图:
\
从表的关联关系可以看出,会员分类跟分类组是多对多的关系,并且分类具有时效性。因此联合FROM_DATE作外键。
将会员划归入一个会员分类:
\

CONTENT_MECH

从这张表开始,我们来看会员的联系方式相关的表结构设计,这也是一部分非常棒的设计。\
这张表存储了联系方式基本信息。它引用了另一张表:CONTENT_MECH_TYPE作为外键,来表示该联系方式的类型(通常的联系方式类型有电话、邮箱、网址等)。

CONTENT_MECH_TYPE

\
可以看到联系方式类型,也是具有层级结构(父子关系)的。
当我们想新建一个联系方式时,首先必须先指定想创建的联系方式的类型:
\

PARTY_CONTACT_MECH

毫无疑问,地址信息只有跟会员联系起来,才能表示会员的地址。而会员跟地址是多对多的关系,理解这个关系时需要注意的是会员可以是任何团体、组织或者个人。那这里可能就会存在两个不同的会员拥有同一个联系方式的可能,比如:一个员工会员与一个该员工所属的公司会员,它们可以都存在同一个联系方式:公司的通讯地址。当然一个会员拥有多个联系方式,这是很容易理解的。所以会员标识跟联系方式标识之间是多对多的关系,并且跟前面的设计模式相似——联系方式也有时效性,比如换电话号码,换工作导致联系方式变化等,所以联合FROM_DATE作为联合主键:
\
当我们选择联系方式类型为电话号码时,会出现如下的表单填写:
\
如果你新建一个联系方式的类型为电话号码,那么电话号码存储在何处?此处又跟前面谈到的HAS_TABLE字段有关(CONTACT_MECH_TYPE中也存在这个字段)。正常情况下,联系方式关联着联系方式类型,普通的联系方式的具体信息存储在CONTACT_MECH的INFO_STRING属性中。但有些联系信息不是单纯的像邮箱这样只是一个字符串,比如像电话号码、邮政编码…它们都有具体的格式表示。所以这些特例用INFO_STRING这一个属性存储也不方便,因此可以独立扩展该CONTACT_MECH_TYPE(将其HAS_TABLE字段设置为Y,这样查询该CONTACT_MECH信息的时候,就不采用INFO_STRING字段,而是采用扩展表中格式化的联系方式)。

CONTACT_MECH_PURPOSE_TYPE

当我们点击上面界面的保存按钮之后,会更进一步得扩充联系信息:
\
在ofbiz中还存在一个称之为“联系目的”的东西,它是什么意思?
\
看到选项我们就会明白,说白了一个人的地址簿或者电话簿中的联系方式可能有很多。它们没有主次之分,只有目的不同。

PARTY_CONTACT_MECH_PURPOSE

上面谈到了联系目的,那么很自然它需要跟会员具体的某条联系信息关联起来才能称之为:某个会员为了某种联系目的存储了一个“联系方式”记录。
\
这里需要注意的是,它并没有跟PARTY_CONTACT_MECH产生直接关联(没有外键关系),而是把PARTY_CONTACT_MECH的三个主键照搬过来,联合CONTACT_MECH_PURPOSE_TYPE_ID形成四个组合主键,这是因为PARTY_CONTACT_MECH的联合主键机制无法被其他表当做外键引用。因此,可以将PARTY_CONTACT_MECH_PURPOSE看作联系信息模块的聚合。这个怎么来理解?其实一个地址可以看成:某个会员(PARTY_ID),出于某种目的(CONTACT_MECH_PURPOSE_TYPE_ID),在某段时间内(FROM_DATE),保存了某个联系方式(CONTACT_MECH_ID)。这种联系方式的设计非常有弹性,因此在大部分情况下,这种抽象性能够涵盖大部分应用场景。

CONTENT_TYPE

会员内容的设计跟联系方式类似。会员可以有一个类似文件空间在服务器上,可以供其保存文档、图片之类的东西。CONTENT_TYPE限定了会员可以存储的内容类型:
\

CONTENT

该表是它的具体存储内容的地方,当然并不是唯一的,如果CONTENT_TYPE有一条记录的HAS_TABLE值为Y,则那个记录对应的表也用于存储内容。内容表里的字段非常多,就不截图了。
跟之前的联系信息类似,会员可以有多个内容,一个内容也可能从属于多个会员。因为会员是个抽象的概念,对应到实体上可能会有重合,所以需要一个“目的”来修饰会员内容,它就是——PARTY_CONTENT_TYPE。

PARTY_CONTENT_TYPE

用于修饰会员内容的用途,当然这里它的表名叫type,事实上从数据记录来看,来时充当了目的的作用。
\
内容还跟其他一些表有关联(主要是被引用关系,比如:CONTENT_ROLE等),此处因为跟本文主题没太大关系,所以不再敖述。

总结

更高的抽象级别

ofbiz party模块的设计,正如它所应用的场景:非常适用于电子商务系统会员信息相关的设计。当然ofbiz中其他相关的多个系统也同样应用了这些表结构,这也意味着它有适用于一般行业、系统的通用性,这得益于这种设计的抽象级别比较高。它可以描述任何的组织、个体、他们的地址信息、他们之间的关系。特别是对会员“relationship”表的设计非常类似于《分析模式》中谈到的责任模式:
系统的用户,又或者一个非常大的跨国公司,拥有:总部、区域销售办公室、办事处、分公司等各种组织形式时,这种设计就会派上用场。

数据库表的继承关系

从PARTY、PARTY_TYPE、PARTY_GROUP、PERSON这几张表我们可以学习到数据库表的“继承”设计。

时效性设计

不是真删除、也不是逻辑删除、而是失效(FROM_DATE, THUR_DATE)。这种方式可以代替“操作-操作历史”的多表设计,转而合并为独立的一张表。
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

iOS 18에는 손실되거나 손상된 사진을 검색할 수 있는 새로운 '복구된' 앨범 기능이 추가되었습니다. iOS 18에는 손실되거나 손상된 사진을 검색할 수 있는 새로운 '복구된' 앨범 기능이 추가되었습니다. Jul 18, 2024 am 05:48 AM

Apple의 최신 iOS18, iPadOS18 및 macOS Sequoia 시스템 릴리스에는 사진 애플리케이션에 중요한 기능이 추가되었습니다. 이 기능은 사용자가 다양한 이유로 손실되거나 손상된 사진과 비디오를 쉽게 복구할 수 있도록 설계되었습니다. 새로운 기능에는 사진 앱의 도구 섹션에 '복구됨'이라는 앨범이 도입되었습니다. 이 앨범은 사용자가 기기에 사진 라이브러리에 포함되지 않은 사진이나 비디오를 가지고 있을 때 자동으로 나타납니다. "복구된" 앨범의 출현은 데이터베이스 손상으로 인해 손실된 사진과 비디오, 사진 라이브러리에 올바르게 저장되지 않은 카메라 응용 프로그램 또는 사진 라이브러리를 관리하는 타사 응용 프로그램에 대한 솔루션을 제공합니다. 사용자는 몇 가지 간단한 단계만 거치면 됩니다.

PHP에서 MySQLi를 사용하여 데이터베이스 연결을 설정하는 방법에 대한 자세한 튜토리얼 PHP에서 MySQLi를 사용하여 데이터베이스 연결을 설정하는 방법에 대한 자세한 튜토리얼 Jun 04, 2024 pm 01:42 PM

MySQLi를 사용하여 PHP에서 데이터베이스 연결을 설정하는 방법: MySQLi 확장 포함(require_once) 연결 함수 생성(functionconnect_to_db) 연결 함수 호출($conn=connect_to_db()) 쿼리 실행($result=$conn->query()) 닫기 연결( $conn->close())

PHP에서 데이터베이스 연결 오류를 처리하는 방법 PHP에서 데이터베이스 연결 오류를 처리하는 방법 Jun 05, 2024 pm 02:16 PM

PHP에서 데이터베이스 연결 오류를 처리하려면 다음 단계를 사용할 수 있습니다. mysqli_connect_errno()를 사용하여 오류 코드를 얻습니다. 오류 메시지를 얻으려면 mysqli_connect_error()를 사용하십시오. 이러한 오류 메시지를 캡처하고 기록하면 데이터베이스 연결 문제를 쉽게 식별하고 해결할 수 있어 애플리케이션이 원활하게 실행될 수 있습니다.

위챗 미니 프로그램 회원가입 방법 위챗 미니 프로그램 회원가입 방법 May 07, 2024 am 10:24 AM

1. WeChat 미니 프로그램을 열고 해당 미니 프로그램 페이지로 들어갑니다. 2. 미니 프로그램 페이지에서 회원 관련 입구를 찾으세요. 일반적으로 회원 입구는 하단 네비게이션 바 또는 개인 센터에 있습니다. 3. 멤버십 포털을 클릭하여 멤버십 신청 페이지로 이동합니다. 4. 회원가입신청 페이지에서 휴대폰번호, 이름 등 관련 정보를 입력하신 후, 가입신청을 해주세요. 5. 미니 프로그램은 회원 가입 신청서를 검토한 후, 사용자는 위챗 미니 프로그램의 회원이 될 수 있습니다. 6. 이용자는 회원이 되면 포인트, 쿠폰, 회원전용 이벤트 등 더 많은 회원권을 누릴 수 있습니다.

Golang에서 데이터베이스 콜백 함수를 사용하는 방법은 무엇입니까? Golang에서 데이터베이스 콜백 함수를 사용하는 방법은 무엇입니까? Jun 03, 2024 pm 02:20 PM

Golang의 데이터베이스 콜백 기능을 사용하면 다음을 달성할 수 있습니다. 지정된 데이터베이스 작업이 완료된 후 사용자 정의 코드를 실행합니다. 추가 코드를 작성하지 않고도 별도의 함수를 통해 사용자 정의 동작을 추가할 수 있습니다. 삽입, 업데이트, 삭제, 쿼리 작업에 콜백 함수를 사용할 수 있습니다. 콜백 함수를 사용하려면 sql.Exec, sql.QueryRow, sql.Query 함수를 사용해야 합니다.

Golang을 사용하여 원격 데이터베이스에 연결하는 방법은 무엇입니까? Golang을 사용하여 원격 데이터베이스에 연결하는 방법은 무엇입니까? Jun 01, 2024 pm 08:31 PM

Go 표준 라이브러리 데이터베이스/sql 패키지를 통해 MySQL, PostgreSQL 또는 SQLite와 같은 원격 데이터베이스에 연결할 수 있습니다. 데이터베이스 연결 정보가 포함된 연결 문자열을 생성합니다. sql.Open() 함수를 사용하여 데이터베이스 연결을 엽니다. SQL 쿼리 및 삽입 작업과 같은 데이터베이스 작업을 수행합니다. 리소스를 해제하기 위해 defer를 사용하여 데이터베이스 연결을 닫습니다.

PEPU 통화 유형 소개 PEPU 통화 유형 소개 Dec 12, 2024 am 11:43 AM

PEPU 코인은 PEPU.io에서 운영하고 PEPU 애플리케이션에서 기본 토큰으로 사용되는 이더리움 블록체인을 기반으로 하는 ERC-20 토큰입니다.

MySQL, PostgreSQL, Oracle 등 다양한 데이터베이스에 대한 PHP 연결 MySQL, PostgreSQL, Oracle 등 다양한 데이터베이스에 대한 PHP 연결 Jun 01, 2024 pm 03:02 PM

PHP 데이터베이스 연결 가이드: MySQL: MySQLi 확장을 설치하고 연결(서버 이름, 사용자 이름, 비밀번호, dbname)을 만듭니다. PostgreSQL: PgSQL 확장을 설치하고 연결(호스트, DB 이름, 사용자, 비밀번호)을 생성합니다. Oracle: OracleOCI8 확장을 설치하고 연결(서버 이름, 사용자 이름, 비밀번호)을 만듭니다. 실제 사례: MySQL 데이터, PostgreSQL 쿼리, OracleOCI8 업데이트 기록을 얻습니다.

See all articles