我试图在标准的sql数据库中建模一个系统,我遇到了以下情况。
我有一个表应该存储源位置。但是有三种位置:URIFileSystem PathID(用于外部服务)。
因此,第一个实现类似于

table my_table (
  id ...,
  uri VARCHAR(2083),
  path VARCHAR(255),
  ext_id VARCHAR(255)
)

此实现有一个缺点:
不能约束不为空(当使用基本的sgbd如mysql时)
若要解决(尝试)此问题,请添加哈希字段:
table my_table (
  id ...,
  uri VARCHAR(2083),
  path VARCHAR(255),
  ext_id VARCHAR(255),
  hash CHAR(32) NOT NULL
)

表示“hash(uri)hash(path)hash(ext_id),另外有助于索引uri(索引> cc>似乎不可能或不有效)
另一个解决方案是合并一列中的所有位置,如下所示
table my_table (
  id ...,
  location VARCHAR(2083) NOT NULL,
  type INT(2) NOT NULL,
  hash CHAR(32)
)

这解决了非空问题,但我们必须使用VARCHAR(2083)并添加VARCHAR(2083)信息作为鉴别器…
我知道这两种解决方案都不是标准化的,但性能是优先考虑的。此表将被大量使用(80%读取-20%写入)。
有什么建议吗?
注:我不能使用任何特定的数据库供应商特性或触发器/存储过程。
编辑:选择的解决方案:
table my_table (
  id ...,
  location VARCHAR(255),
  type SMALLINT
)

如何管理超过255的uri?
经过数据分析,我发现uri超过255是非常罕见的情况。我的实际数据模型(在这个新模型之前)将uri存储在type上,所以对我来说没有回归。
我计划实现一个url shortener服务来管理uri>255的1%的情况。
我不想在1%的用例中限制99%的通用性。
为什么不保持VARCHAR(255)
一个原因是mysql引擎无法将VARCHAR(2083)设置为UNIQUE constraint
为什么要删除散列字段?
我认为(可能是错误的)VARCHAR(2083)索引已经足够了,所有数据库供应商都应该正确地管理它。

最佳答案

合并所有列似乎很好。您可以将引用表用于所使用的位置类型。因此,可以在合并表中使用typeid,并且不管位置的类型如何,都将填充该位置。不过,我不知道你从散列中得到了多少好处。
我的桌子(
身份证件。。。,
位置varchar(2083)不为空,
typeid int(1)不为空-->对位置类型的FK引用

表位置类型(
typeid int(1)不为空,
typename varchar(100)不为空

还忘了回答您对使用varchar(2003)的疑问。varchar列是可变长度的列。因此,当您创建一个列作为varchar(50)并用值“abc”填充它时,只存储5个字节,数据长度为2个字节,值“abc”为3个字节。所以不会占用额外的空间。

关于mysql - 数据库建模-具有相同行为但数据类型不同的列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29767482/

10-13 07:14
查看更多