7

外部キーはパーティション化された mySQL データベースでは現時点ではサポートされていないため、テーブルごとに約 1 ~ 400 000 行を処理する読み取り負荷の高いアプリケーションについて、賛否両論を聞きたいと思います。残念ながら、私はこの分野で自分で結論を出すのに十分な経験がありません...

どうもありがとう!

参考文献:

パーティショニング中に外部キーを処理する方法

外部キーを持つ mySQL テーブルを分割しますか?

4

2 に答える 2

4

400.000 行ほどの小さなテーブルのパーティション分割が必要な場合は、MySQL 以外の別のデータベースを取得します。真剣に。現代の標準では、1.000.000 行未満のテーブルは通常、サイズが無視できます (小さくさえありません)。ただし、インデックスなどがない場合を除きます。また、現代の標準は、この点で約 10 年前のものです。

于 2010-03-24T23:37:43.437 に答える
1

パーティションは、複雑なデータ モデルの適切なソリューションではありません。相互に依存するテーブルが 2 ~ 3 個しかない場合は、できるかもしれませんが、見栄えがよくありません。各テーブルには、パーティションを決定する列が必要です。次に、各テーブルには、新しいテーブルを作成し、外部キーと一意制約を設定するためのトリガーが必要です。

たとえば、audittransaction<-auditentry

各監査トランザクションには、0 から n 個の監査エントリがあります。テーブル auditentry には、トランザクションの外部キーが含まれています。両方のテーブルを分割するために使用されるため、両方のテーブルに列 creationDate が必要です。

------ トリガーを作成して、トリガー内に audittransaction を挿入します

create or replace function audittransaction_insert_function() 
returns trigger as $$ 
DECLARE

    tablepartition varchar;
    tablename varchar;
    startbounds timestamp;
    endbounds timestamp;                


BEGIN
    tablepartition :=  to_char(date_trunc('month', NEW.whendone), 'YYYYMMDD');  
    tablename := 'audittransaction_' || tablepartition ;        

    if not exists(select * from information_schema.tables where table_name = tablename) then
        startbounds := date_trunc('month', NEW.whendone);
        endbounds := startbounds + cast('1 months' as interval);
        execute 'create table ' || tablename || ' ( CHECK (whendone >= ' || quote_literal(startbounds) || ' and whendone < ' || quote_literal(endbounds)|| ') ) inherits (audittransaction)';
        execute 'ALTER TABLE '||  tablename ||' ADD CONSTRAINT '||tablename||'_unique_id UNIQUE (id)';          
    end if;     
    execute 'insert into ' || tablename || ' (id, operationid, whendone, "comment", ticketid ,transactionid, userid )  values (' || quote_literal(NEW.id) || ',' || quote_literal(NEW.operationid) || ',' || quote_literal(NEW.whendone) || ')';                
    return null; 
END; $$ 
LANGUAGE plpgsql;

create trigger insert_audittrans

----- 次に、auientry のトリガーを作成します。

create or replace function auditentry_insert_function() 
returns trigger as $$ 
DECLARE
    tablepartition varchar;
    tablename varchar;
    startbounds timestamp;
    endbounds timestamp;                


BEGIN
    tablepartition :=  to_char(date_trunc('month', NEW.transactiontimestampgmt), 'YYYYMMDD');   
    tablename := 'auditentry_' || tablepartition ;

    if not exists(select * from information_schema.tables where table_name = tablename) then
        startbounds := date_trunc('month', NEW.transactiontimestampgmt);
        endbounds := startbounds + cast('1 months' as interval);
        execute 'create table ' || tablename || ' ( CHECK (transactiontimestampgmt >= ' || quote_literal(startbounds) || ' and transactiontimestampgmt < ' || quote_literal(endbounds)|| ') ) inherits (auditentry)';
        execute 'ALTER TABLE '||  tablename ||' ADD CONSTRAINT '||tablename||'_unique_id UNIQUE (id)';  
        execute 'ALTER TABLE ' || tablename ||' ADD CONSTRAINT auditentry FOREIGN KEY (audit_transaction_id) REFERENCES audittransaction_'||tablepartition ||'(id)';                
    end if;     
    execute 'insert into ' || tablename || ' (id, audit_transaction_id, eventid, transactiontimestampgmt,timestampgmt, acknowledged, resolved, acknowledgedbyusername, acknowledgeddate,  notificationlevel, resolvedbyusername, resolveddate, severity,  parentauditentry_id )  values (' || quote_literal(NEW.id) || ',' || quote_literal(NEW.audit_transaction_id) || ',' || quote_literal(NEW.eventid) || ','||quote_literal(NEW.transactiontimestampgmt)||')';             
    return null; 
END; $$ 
LANGUAGE plpgsql;

create trigger insert_auditentry before insert on auditentry for each row execute procedure auditentry_insert_function();
于 2010-12-14T02:41:46.380 に答える