2017-04-04 94 views
0

我有一个存储对象属性的表。每个属性在表中都有它自己的行,并且它引用另一个表中的对象ID。属性目前是布尔类型(0),数字(1)或自由文本(2),它们存储单个值。列中的不同数据类型

问题是,我该如何确定哪一行是哪一种?属性表是否有一个名为type的列,然后将该值存储在单独的TEXT列中,或者可能将该值存储为JSON对象?有没有一个好的解决方案呢?我相信我在这里担心的是保存数据类型,如果数据存储在TEXT列中,则可能难以处理。

我的直觉告诉我,将类型和值存储在JSON对象中将成为这里的一种方式。

对象表:

id | name 
-----+----- 
123 | abc 

思路属性表:

id | object_id | type | data 
----+-----------+------+------- 
    1 | 123  | 1 | 123.12 
    2 | 123  | 0 | f 

的属性表的其他想法:

id | object_id | type | data 
----+-----------+----------------------- 
    1 | 112  | 1 | {value:123.12} 
    2 | 112  | 0 | {value:false} 
+0

'pg_typeof(column_name)'会告诉你类型 –

+0

我想在单个列中存储不同类型的数据并保留它们的数据类型,所以我不认为'pg_typeof()'会帮助我。我编辑了标题以更好地描述我的问题。 – Nysten

+0

然后考虑使用json数据类型而不是文本 –

回答

1

每列必须有PostgreSQL中确定的类型,所以你不能有一个可以容纳不同类型的字段。

如果您需要数据库中的属性,那么使用JSON将无济于事,因为您只能从JSON值获取text

我会用这三个表,每种类型:

CREATE TABLE bool_property (
    id integer PRIMARY KEY, 
    object_id integer NOT NULL REFERENCES object(id), 
    data boolean NOT NULL 
); 

CREATE TABLE num_property (
    id integer PRIMARY KEY, 
    object_id integer NOT NULL REFERENCES object(id), 
    data numeric NOT NULL 
); 

CREATE TABLE text_property (
    id integer PRIMARY KEY, 
    object_id integer NOT NULL REFERENCES object(id), 
    data text NOT NULL 
); 

另外,如果你想有一个单一的表,使用

CREATE TABLE property (
    id integer PRIMARY KEY, 
    object_id integer NOT NULL REFERENCES object(id), 
    datatype regtype NOT NULL, 
    bool_data boolean, 
    num_data numeric, 
    text_data text, 
    CHECK (CASE datatype 
      WHEN 'boolean'::regtype 
      THEN bool_data IS NOT NULL 
       AND num_data IS NULL 
       AND text_data IS NULL 
      WHEN 'numeric'::regtype 
      THEN bool_data IS NULL 
       AND num_data IS NOT NULL 
       AND text_data IS NULL 
      WHEN 'text'::regtype 
      THEN bool_data IS NULL 
       AND num_data IS NULL 
       AND text_data IS NOT NULL 
      ELSE FALSE 
      END 
     ) 
); 

但可能是比较困难的连接。