2010-03-24 15 views
7

Étant donné que les clés étrangères ne sont pas supportées par les bases de données mySQL partitionnées pour le moment, j'aimerais connaître les avantages et les inconvénients d'une application très lisible qui gère environ 1 400 000 lignes par table. Malheureusement, je n'ai pas encore assez d'expérience dans ce domaine pour faire la conclusion par moi-même ...Clés étrangères vs partitionnement

Merci beaucoup!

Références:

How to handle foreign key while partitioning

Partitioning mySQL tables that has foreign keys?

Répondre

4

Eh bien, si vous avez besoin de partitionnement pour une table aussi petites que les lignes obtenir une autre 400.000 base de données de MySQL. Sérieusement. Selon les normes modernes, toute table en dessous de 1.000.000 lignes est normalement de taille neglegible (pas même petite), sauf si vous n'avez pas non plus d'indice, etc Et les normes modernes sont d'environ 10 ans à cet égard.

+0

Eh bien, Non, je ne pourrais pas Ne trouvez pas de recommandations pour partitionner ou non. J'ai supposé que cela ferait une différence notable pour les petites tables aussi. – Industrial

+1

Non. Partitionnement est essentiellement lorsque vous rencontrez des problèmes avec une table. En théorie par exemple parce que vous gardez les ventes par an - la suppression de toutes les ventes pour une année est un travail très difficile, mais avec des partitions, vous pouvez simplement laisser tomber la table pour l'année. Les petites choses n'ont aucun sens comme ça. – TomTom

+0

Merci beaucoup TomTom. Appréciez votre réponse. La suppression de travailler avec des partitions est évidente, mais d'après ce que j'ai entendu précédemment, une table partitionnée fonctionnait toujours mieux qu'une partition non partitionnée, même avec des ensembles de données plus petits. Je n'ai aucune idée de la comparaison dans l'augmentation de la performance avec des clés étrangères sur les partions cependant. On dirait un sujet avec peu d'informations sur. Peut-être devrais-je aller à la dure pour découvrir avec l'analyse comparative et des exemples de données ... – Industrial

1

Eh bien, la partition n'est pas une bonne solution pour un modèle de données compliqué. Si vous n'avez que 2 ou 3 tables en fonction les unes des autres, vous pourrez peut-être le faire mais ce n'est pas joli. Chaque table doit avoir une colonne qui détermine la partition. Ensuite, chaque table doit avoir un déclencheur pour créer la nouvelle table, définir la clé étrangère et la contrainte unique.

Par exemple, audittransaction < - auditentry

Chaque audittransactionhas 0 à n auditentry. table auditentry contient la clé étrangère de la transaction. Les deux tables doivent avoir la colonne creationDate car elle est utilisée pour partitionner les deux tables.

------ créer un déclencheur pour insérer audittransaction dans le déclencheur

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 

----- puis, créer un déclencheur pour 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();