如果这确实是最好的方法(我怀疑是),那么在数据库中映射这一点的最好方法是什么?最好保留一个“类型”列,然后将其设置为一个或另一个?
我认为在给定的场景下,没有明确的“最佳方法”来设计数据库结构。课本答案是
database normalization
和
DRY
.
三表法
例如,一种方法可以是创建包含这两种类型用户的用户表,只存储公共属性,并创建学生表和提供程序表,其中包含用户表的外键和专用属性(如果有)。这可能不是传统关系数据库人员所推荐的,但它更接近于OO继承模型。
单表法
如您所说的另一种方法是只创建一个“usertype”字段,并将这两种类型的用户存储到用户表中。这很简单,但是您会错过利用关系数据库的引用完整性的机会。例如,如果要创建只针对学生的子表,例如家庭作业,那么如果学生和提供者都住在用户表中,就不能简单地将外键设置为studentid。
双表法
如果您使用的是对象关系映射框架,那么最简单的方法可能是将对象世界海峡中您想要的东西精确映射到数据库中,该数据库将具有student表和provider表,并将两者的共性表示为scala端的特征。
我找到电梯了
cheat sheet
:
定义模型
Lift O-R映射模型是基于带字段的类定义的。
class WikiEntry extends KeyedMapper[Long, WikiEntry] {
def getSingleton = WikiEntry // what's the "meta" object
def primaryKeyField = id
// the primary key
object id extends MappedLongIndex(this)
// the name of the entry
object name extends MappedString(this, 32) {
override def dbIndexed_? = true // indexed in the DB
}
object owner extends MappedLongForeignKey(this, User)
// the text of the entry
object entry extends MappedTextarea(this, 8192) {
override def textareaRows = 10
override def textareaCols = 50
}
}
关于拥有的讨论
shared base traits for Models
.
大卫·波拉克在书中写道:
你在寻找斯卡拉魔法:
trait Posting[MyType <: Mapper[MyType]] { // Defines some common fields for posted user content
self: MyType =>
def primaryKeyField = id
object id extends MappedLongIndex(this)
object creator extends MappedLongForeignKey(this, User)
object createdAt extends MappedLong(this) {
override def defaultValue = System.currentTimeMillis
}
}
class FooPosting extends KeyedMapper[FooPosting] with Posting[MyType]