MySQL Workbench 手冊  /  ...  /  教學:使用 MyISAM 產生外鍵

C.6.2 教學:使用 MyISAM 產生外鍵

EER 圖表對於視覺化複雜的資料庫結構很有用。它們通常是為現有資料庫建立的,以釐清其目的或記錄它們。MySQL Workbench 提供對現有資料庫進行反向工程,然後自動建立 EER 圖表的功能。在這種情況下,將會自動繪製表格中外鍵之間的關係線。這種圖形表示法使得表格之間的關係更容易理解。然而,較舊的 MyISAM 儲存引擎不支援外鍵。這表示反向工程的 MyISAM 表格不會自動在表格之間繪製關係線,使得資料庫更難理解。本教學中建立的外掛程式透過使用外鍵通常使用的命名慣例來解決此問題:表格名稱_主鍵名稱。使用此慣例,可以在反向工程資料庫後自動建立外鍵,這將導致在 EER 圖表中繪製關係線。

演算法

此任務的基本演算法如下

for each table in the schema
   for each column in the table
      look for another table whose name and primary key name match the current column name
      if such a table is found, add a foreign key referencing it

由於迭代完整的表格清單以尋找比對對於具有大量表格的模型來說可能會很慢,因此有必要透過預先計算給定結構描述中所有可能的外鍵名稱來最佳化。

import grt

def auto_create_fks(schema):
   fk_name_format = "%(table)s_%(pk)s"
   possible_fks = {}
   # create the list of possible foreign keys from the list of tables
   for table in schema.tables:
      if table.primaryKey:
         format_args = {'table':table.name, 'pk':table.primaryKey.name}
         fkname = fk_name_format % format_args
         possible_fks[fkname] = table

   # go through all tables in schema, this time to find columns that may be a fk
   for table in schema.tables:
      for column in table.columns:
         if possible_fks.has_key(column.name):
            ref_table = possible_fks[column.name]
            if ref_table.primaryKey.formattedType != column.type:
               continue
            fk = table.createForeignKey(column.name+"_fk")
            fk.referencedTable = ref_table
            fk.columns.append(column)
            fk.referencedColumn.append(ref_table.primaryKey)
            print "Created foreign key %s from %s.%s to %s.%s" \
            % (fk.name, table.name, column.name, ref_table.name, ref_table.primaryKey.name)

auto_create_fks(grt.root.wb.doc.physicalModels[0].catalog.schemata[0])

從指令碼建立外掛程式

若要從任意指令碼建立外掛程式,首先必須將該檔案設為模組,並從中匯出所需的函式。然後必須將該模組宣告為外掛程式,並指定傳回類型和輸入引數。

from wb import *
import grt

ModuleInfo = DefineModule(name="AutoFK", author="John Doe", version="1.0")

@ModuleInfo.plugin("sample.createGuessedForeignKeys",
  caption="Create Foreign Keys from ColumnNames",
  input=[wbinputs.objectOfClass("db.mysql.schema")],
  groups=["Overview/Utility"])

@ModuleInfo.export(grt.INT, grt.classes.db_mysql_Schema)
def auto_create_fks(schema):
   ...

新增上述程式碼後,auto_create_fks() 函式將會匯出,並新增至模型概觀中的結構描述內容選單。當呼叫時,它會接收目前選取的結構描述作為其輸入。