粒度指的是你所需要的对象的个数问题。当我们在讨论Java对象和数据库表的时候,粒度问题通常指的是对象和数据库表以及列之间的匹配问题,对于数据库表和数据列来说,粒度是一定的,而对于同样的数据库表和数据列来说,Java对象却可以有很多种粒度可以选择。
让我们回到我们的例子。在数据库表中添加一列来存取Java中的Address类型是一个最好的选择。可以说,Java的Address类型和数据库的Address(SQL数据类型)能够保持最好的操作性。但是,实际情况是当你在数据库中想是使用自定义类型(UDT)的时候,你会发现很多问题。
支持UDT的关系数据库被看作是关系型数据库对关系/对象的一种扩展。不幸的是,大部分关系型数据库对于UDT的支持并不好,而且在不同的系统中不能互相兼容。SQL标准虽然支持用户自定义的类型,但是功能方面还有待商榷。因此,对于目前的情况来说,使用用户自定义的类型并不是一个可行的办法,而且你也不可能像传统的schema那样来使用UDT。因此,我们不能将Java中的Address对象单独的存在数据库表中某一列。我们的做法是用几列来代替用户自定义的类型(UDT)。重新考虑数据库表的粒度,我们将USER表重新定义:
create table USER(
USERNAME VARCHAR(12) NOT NULL PRIMARY KEY,
NAME VARCHAR(50) NOT NULL,
ADDRESS_STREET VARCHAR(50),
ADDRESS_CITY VARCHAR(15),
ADDRESS_STATE VARCHAR(15),
ADDRESS_ZIPCODE VARCHAR(5),
ADDRESS_COUNTRY VARCHAR(15)
)
通过这样的设计,我们能够得出一个不同层次的粒度,粗粒度的User和细粒度的Address,以及非常简单的类型如Zipcode。
与此相反的是,两层的粒度来数据中显得非常清晰,但是与Java类型相比,它们并不具有很大的弹性。许多简单的持久化机制并不能识别这种不匹配,这样造成的后果就是限制Java对象原有的弹性,后果就是出现了例如Zipcode这样的属性直接出现在User类当中。
从上面的例子来看,粒度问题似乎并不难解决。然而现实系统中的应用往往不会如此简单。在第三章的3.5节我们会给出解决方案。
当我们考虑类的继承关系的时候,问题会变得更加的复杂。