2010-03-24 19 views
7

Dado que las claves foráneas no son soportadas por bases de datos mySQL particionadas por el momento, me gustaría escuchar algunos pro y contras para una aplicación de lectura pesada que manejará alrededor de 1-400 000 filas por tabla. Lamentablemente, todavía no tengo suficiente experiencia en esta área para hacer la conclusión por mi cuenta ...Claves foráneas vs partición

¡Muchas gracias!

Referencias:

How to handle foreign key while partitioning

Partitioning mySQL tables that has foreign keys?

Respuesta

4

Bueno, si necesita de partición para una mesa tan pequeña como 400.000 filas consiguen otra base de datos de MySQL. Seriamente. Según los estándares modernos, cualquier tabla por debajo de 1.000.000 de filas es normalmente de tamaño negruzco (ni siquiera pequeña), a menos que tampoco tenga ningún índice, etc. Y los estándares modernos tienen alrededor de 10 años en este aspecto.

+0

Bueno, yo no podía No. No encuentra ninguna recomendación sobre si dividir o no. Supuse que también marcaría una diferencia notable para las mesas pequeñas. – Industrial

+1

No. El particionamiento es básicamente cuando te encuentras con problemas para tener una mesa. En teoría, por ejemplo, porque usted mantiene las ventas por año; eliminar todas las ventas durante un año es realmente un trabajo duro, pero con las particiones puede simplemente dejar la mesa por un año. Las cosas pequeñas no tienen sentido así. – TomTom

+0

Muchas gracias TomTom. Aprecia tu respuesta La eliminación de trabajar con particiones es obvia, pero por lo que he escuchado anteriormente, una tabla particionada siempre funcionó mejor que una sin particiones, incluso con conjuntos de datos más pequeños. Sin embargo, no tengo idea de la comparación en el aumento de rendimiento con claves externas sobre partions. Parece un tema con poca información sobre. Tal vez tendré que ir por el camino difícil para averiguar con datos de referencia y muestra ... – Industrial

1

Bueno, la partición no es una buena solución para complicar el modelo de datos. Si solo tiene de 2 a 3 tablas, dependiendo la una de la otra, es posible que pueda hacerlo, pero no es bonita. Cada tabla debe tener una columna que determine la partición. Luego, cada tabla debe tener un activador para crear la nueva tabla, establecer la clave externa y la restricción única.

Por ejemplo, audittransaction < - auditentry

Cada audittransactionhas 0 a n auditentry. table auditentry contiene la clave externa de la transacción. Ambas tablas tienen que tener la columna creationDate ya que se usa para la partición de ambas tablas.

------ crear un disparador para insertar audittransaction dentro del disparador

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 

----- continuación, crear un disparador para 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(); 
Cuestiones relacionadas