2010-03-24 6 views
7

Da Fremdschlüssel im Moment nicht von partitionierten MySQL-Datenbanken unterstützt werden, möchte ich einige Pro und Kontra für eine rechenintensive Anwendung hören, die etwa 1-400 000 Zeilen pro Tabelle verarbeiten kann. Leider habe ich noch nicht genug Erfahrung in diesem Bereich, um die Schlussfolgerung selbst zu machen ...Fremdschlüssel vs Partitionierung

Vielen Dank!

Referenzen:

How to handle foreign key while partitioning

Partitioning mySQL tables that has foreign keys?

Antwort

4

Nun, wenn Sie Partitionierung für eine Tabelle so klein wie 400.000 Zeilen benötigen bekommen eine andere Datenbank als MySQL. Ernst. Nach heutigen Maßstäben ist jede Tabelle unter 1.000.000 Zeilen normalerweise in der Größe vernachlässigbar (nicht einmal klein), es sei denn, Sie haben auch keinen Index usw. Und moderne Standards sind in dieser Hinsicht ungefähr 10 Jahre alt.

+0

Nun, Nein, ich couldn Finde keine Empfehlungen, ob du partitionieren willst oder nicht. Ich nahm an, dass es auch für kleine Tische einen spürbaren Unterschied machen würde. – Industrial

+1

Nein. Partitionierung ist im Grunde, wenn Sie Probleme mit einem Tisch haben. In der Theorie zum Beispiel, weil Sie den Umsatz pro Jahr halten - Löschen aller Verkäufe für ein Jahr ist wirklich harte Arbeit, aber mit Partitionen können Sie einfach die Tabelle für das ein Jahr fallen lassen. Kleine Dinge machen null Sinn. – TomTom

+0

Vielen Dank TomTom. Schätze deine Antwort. Der Löschteil beim Arbeiten mit Partitionen ist offensichtlich, aber von dem, was ich zuvor gehört habe, funktionierte eine partitionierte Tabelle immer besser als eine nicht partitionierte, selbst mit kleineren Datensätzen. Ich habe jedoch keine Vorstellung vom Leistungsvergleich mit Fremdschlüsseln gegenüber Partitionen. Scheint wie ein Thema mit wenig Informationen über. Vielleicht muss ich den harten Weg gehen, um mit Benchmarking und Beispieldaten herauszufinden ... – Industrial

1

Nun, Partition ist keine gute Lösung für komplizierte Datenmodell. Wenn Sie nur 2 bis 3 Tabellen haben, können Sie es zwar tun, aber es ist nicht schön. Jede Tabelle muss eine Spalte enthalten, die die Partition bestimmt. Dann muss jede Tabelle einen Trigger haben, um die neue Tabelle zu erstellen, den Fremdschlüssel und die Eindeutigkeitsbedingung festzulegen.

Zum Beispiel audittransaction < - auditentry

Jede audittransactionhas 0 bis n auditentry. table auditentry enthält den Fremdschlüssel der Transaktion. Beide Tabellen müssen eine Spalte creationDate haben, da sie für beide Tabellen verwendet wird.

------ erstellen einen Auslöser zum Einfügen audittransaction innerhalb des Triggers

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 

----- dann erstellen Sie einen Trigger für autientry

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();