2012-06-27 53 views
1

我們在postgresql數據庫中有一個小型數據倉庫,我必須記錄所有的表。如何處理數據倉庫(postgressql)文檔?

我想我可以給每個列和表添加註釋並使用管道「|」分隔符來添加更多屬性。然後我可以使用信息模式和數組函數來獲取文檔並使用任何報告軟件來創建所需的輸出。

select 
    ordinal_position, 
    column_name, 
    data_type, 
    character_maximum_length, 
    numeric_precision, 
    numeric_scale, 
    is_nullable, 
    column_default, 
    (string_to_array(descr.description,'|'))[1] as cs_name, 
    (string_to_array(descr.description,'|'))[2] as cs_description, 
    (string_to_array(descr.description,'|'))[3] as en_name, 
    (string_to_array(descr.description,'|'))[4] as en_description, 
    (string_to_array(descr.description,'|'))[5] as other 
from 
    information_schema.columns columns 
    join pg_catalog.pg_class klass on (columns.table_name = klass.relname and klass.relkind = 'r') 
    left join pg_catalog.pg_description descr on (descr.objoid = klass.oid and descr.objsubid = columns.ordinal_position) 
where 
    columns.table_schema = 'data_warehouse' 
order by 
    columns.ordinal_position; 

這是一個好主意還是有更好的方法?

+0

歡迎來到StackOverflow! –

回答

3

除非您必須包含系統表的描述,否則我不會試圖將您的描述放在pg_catalog.pg_description中。製作你自己的桌子。這樣你可以將列保留爲列,而不必使用笨重的字符串函數。

或者,考慮將特殊格式的註釋添加到您的主模式文件中,沿着javadoc的行。然後編寫一個工具來提取這些評論並創建一個文檔。這樣,評論就會貼近他們所評論的內容,而且您根本不必亂用數據庫來生成報告。例如:

--* Used for authentication. 
create table users 
(
    --* standard Rails-friendly primary key. Also an example of 
    --* a long comment placed before the item, rather than on the 
    --* the same line. 
    id serial primary key, 
    name text not null,  --* Real name (hopefully) 
    login text not null, --* Name used for authentication 
    ... 
); 

你的文檔工具讀取文件,將查找--*意見,斷定哪些評論去什麼東西,併產生某種報告,例如:

table users: Used for authentication 
    id: standard Rails-friendly primary key. Also an example of a 
     long comment placed before the item, rather than on the same 
     line. 
    name: Real name 
    login: Name used for authentication 

你可能請注意,通過適當的評論,主模式文件本身就是一個非常好的報告,可能沒有其他需要。

+0

謝謝你的回答。我將創建一個單獨的表格來記錄表格和屬性。 –

1

如果有人感興趣,這裏是我用於初始加載我的小文檔項目。文檔有兩個表格,一個用於描述表格,另一個用於描述列和約束。我很欣賞任何反饋。

/* -- Initial Load - Tables */ 

drop table dw_description_table cascade; 

create table dw_description_table (
    table_description_key serial primary key, 
    physical_full_name character varying, 
    physical_schema_name character varying, 
    physical_table_name character varying, 
    Table_Type character varying, -- Fact Dimension ETL Transformation 
    Logical_Name_CS character varying, 
    Description_CS character varying, 
    Logical_Name_EN character varying, 
    Description_EN character varying, 
    ToDo character varying, 
    Table_Load_Type character varying, --Manually TruncateLoad AddNewRows 
    Known_Exclusions character varying, 
    Table_Clover_Script character varying 
); 



insert into dw_description_table (physical_full_name, physical_schema_name, physical_table_name) (

select 
    table_schema || '.' || table_name as physical_full_name, 
    table_schema, 
    table_name 
from 
    information_schema.tables 
where 
    table_name like 'dw%' or table_name like 'etl%' 
) 


/* -- Initial Load - Columns */ 


CREATE TABLE dw_description_column (
    column_description_key serial, 
    table_description_key bigint, 
    physical_full_name text, 
    physical_schema_name character varying, 
    physical_table_name character varying, 
    physical_column_name character varying, 
    ordinal_position character varying, 
    column_default character varying, 
    is_nullable character varying, 
    data_type character varying, 
    logical_name_cs character varying, 
    description_cs character varying, 
    logical_name_en character varying, 
    description_en character varying, 
    derived_rule character varying, 
    todo character varying, 
    pk_name character varying, 
    fk_name character varying, 
    foreign_table_name character varying, 
    foreign_column_name character varying, 
    is_primary_key boolean, 
    is_foreign_key boolean, 
    CONSTRAINT dw_description_column_pkey PRIMARY KEY (column_description_key), 
    CONSTRAINT fk_dw_description_table_key FOREIGN KEY (table_description_key) 
     REFERENCES dw_description_table (table_description_key) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
); 




insert into dw_description_column ( 
    table_description_key , 
    physical_full_name , 
    physical_schema_name , 
    physical_table_name , 
    physical_column_name , 
    ordinal_position , 
    column_default , 
    is_nullable , 
    data_type , 
    logical_name_cs , 
    description_cs , 
    logical_name_en , 
    description_en , 
    derived_rule , 
    todo , 
    pk_name , 
    fk_name , 
    foreign_table_name , 
    foreign_column_name , 
    is_primary_key , 
    is_foreign_key) 

(

with 

dw_constraints as (
SELECT 
    tc.constraint_name, 
    tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name, 
    tc.constraint_schema, 
    tc.table_name, 
    kcu.column_name, 
    ccu.table_name AS foreign_table_name, 
    ccu.column_name AS foreign_column_name, 
    TC.constraint_type 
FROM 
    information_schema.table_constraints AS tc 
    JOIN information_schema.key_column_usage AS kcu ON (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name) 
    JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name 
WHERE 
    constraint_type in ('PRIMARY KEY','FOREIGN KEY') 
    AND tc.constraint_schema = 'bizdata' 
    and (tc.table_name like 'dw%' or tc.table_name like 'etl%') 
group by 
    tc.constraint_name, 
    tc.constraint_schema, 
    tc.table_name, 
    kcu.column_name, 
    ccu.table_name , 
    ccu.column_name, 
    TC.constraint_type 

) 

select 
    dwdt.table_description_key, 
    col.table_schema || '.' || col.table_name || '.' || col.column_name as physical_full_name, 
    col.table_schema as physical_schema_name, 
    col.table_name as physical_table_name, 
    col.column_name as physical_column_name, 
    col.ordinal_position, 
    col.column_default, 
    col.is_nullable, 
    col.data_type, 
    null as Logical_Name_CS , 
    null as Description_CS , 
    null as Logical_Name_EN, 
    null as Description_EN , 
    null as Derived_Rule , 
    null as ToDo, 
    dwc1.constraint_name pk_name, 
    dwc2.constraint_name as fk_name, 
    dwc2.foreign_table_name, 
    dwc2.foreign_column_name, 
    case when dwc1.constraint_name is not null then true else false end as is_primary_key, 
    case when dwc2.constraint_name is not null then true else false end as foreign_key 
from 
    information_schema.columns col 
    join dw_description_table dwdt on (col.table_schema || '.' || col.table_name = dwdt.physical_full_name) 
    left join dw_constraints dwc1 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc1.physical_full_name and dwc1.constraint_type = 'PRIMARY KEY') 
    left join dw_constraints dwc2 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc2.physical_full_name and dwc2.constraint_type = 'FOREIGN KEY') 
where 
    col.table_name like 'dw%' or col.table_name like 'etl%' 
)