如何将外键约束应用于musicbrainz数据库?

时间:2014-08-29 00:50:53

标签: postgresql musicbrainz

我在将外键应用到postgres musicbrainz数据库时遇到了困难 我用这些优秀的指示来解决这个问题:
https://bitbucket.org/lalinsky/mbslave
我把所有的数据加载到postgres中 我创建了主键和索引。

然而,当我尝试应用外键时,我得到了这个奇怪的错误:

musicbrainz@ip-10-217-5-18:/home/ubuntu/mbslave$ psql < sql/CreateFKConstraints.sql 
ERROR:  insert or update on table "annotation" violates foreign key constraint "annotation_fk_editor"
DETAIL:  Key (editor)=(51298) is not present in table "editor".

在SQL脚本的第一行似乎有错误:

ALTER TABLE annotation
   ADD CONSTRAINT annotation_fk_editor
   FOREIGN KEY (editor)
   REFERENCES editor(id);

我是postgres的新手,我很难理解这条错误信息。

第一行让我相信已经创建了外键约束。 但我不认为它有。

musicbrainz=> SELECT
musicbrainz->     tc.constraint_name, tc.table_name, kcu.column_name, 
musicbrainz->     ccu.table_name AS foreign_table_name,
musicbrainz->     ccu.column_name AS foreign_column_name 
musicbrainz-> FROM 
musicbrainz->     information_schema.table_constraints AS tc 
musicbrainz->     JOIN information_schema.key_column_usage AS kcu
musicbrainz->       ON tc.constraint_name = kcu.constraint_name
musicbrainz->     JOIN information_schema.constraint_column_usage AS ccu
musicbrainz->       ON ccu.constraint_name = tc.constraint_name
musicbrainz-> WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='annotation';
 constraint_name | table_name | column_name | foreign_table_name | foreign_column_name 
-----------------+------------+-------------+--------------------+---------------------
(0 rows)

错误消息中的第二行令人困惑。 听起来它无法在编辑器表中找到id列。 但它就在那里。

musicbrainz=> \d editor
                                      Table "musicbrainz.editor"
       Column        |           Type           |                      Modifiers                      
---------------------+--------------------------+-----------------------------------------------------
 id                  | integer                  | not null default nextval('editor_id_seq'::regclass)
 name                | character varying(64)    | not null
 privs               | integer                  | default 0
 email               | character varying(64)    | default NULL::character varying
 website             | character varying(255)   | default NULL::character varying
 bio                 | text                     | 
 member_since        | timestamp with time zone | default now()
 email_confirm_date  | timestamp with time zone | 
 last_login_date     | timestamp with time zone | default now()
 edits_accepted      | integer                  | default 0
 edits_rejected      | integer                  | default 0
 auto_edits_accepted | integer                  | default 0
 edits_failed        | integer                  | default 0
 last_updated        | timestamp with time zone | default now()
 birth_date          | date                     | 
 gender              | integer                  | 
 area                | integer                  | 
 password            | character varying(128)   | not null
 ha1                 | character(32)            | not null
 deleted             | boolean                  | not null default false
Indexes:
    "editor_pkey" PRIMARY KEY, btree (id)
    "editor_idx_name" UNIQUE, btree (lower(name::text))

建议?

1 个答案:

答案 0 :(得分:1)

约束:

ALTER TABLE annotation
   ADD CONSTRAINT annotation_fk_editor
   FOREIGN KEY (editor)
   REFERENCES editor(id);

表示在表annotation中,该表中的列editor也必须存在于editor列下的表id中。

基本上,它确保数据库中存在editor中使用的所有id annotation

这有助于维护参照完整性。如果没有外键约束,任何事情都可能存在,无论它是否实际位于editor表中,这可能会导致一大堆与数据相关的问题。

错误消息:

  

错误:表“插入”上的插入或更新违反了外键   约束“annotation_fk_editor”DETAIL:键(编辑)=(51298)不是   出现在表格“编辑”中。

表示id表中没有editor 51298 的行。

该表中是否有任何数据?

您可以通过在annotations上对\d执行editor来启用FK约束。 (您可能需要\d+才能获取所有信息。)

此外,虽然之前我没有使用 MusicBrainz ,但BitBucket链接包含两个突出的问题,可能会导致您的问题:

  1. 主页面上的设置说明似乎没有应用FK约束
  2. 设置说明也正在使用名为 mbslave-remap-schema.py Python 包装器,它正在做一些 sed - 比如替换SQL文本以更改模式等等,并将其输出汇总到 psql 的包装中,命名为 mbslave-psql.py 而不是 psql 直接
  3. sql文件似乎都与模式相关,并且数据本身似乎是使用不同的包装器从转储导入的:./mbslave-import.py mbdump.tar.bz2 mbdump-derived.tar.bz2(显然没有整个数据库转储,或者至少没有一个很明显的)