Внешние ключи против разбиения - PullRequest
7 голосов
/ 25 марта 2010

Поскольку внешние ключи на данный момент не поддерживаются многораздельными базами данных mySQL, я хотел бы услышать некоторые плюсы и минусы для приложения с высокой нагрузкой на чтение, которое будет обрабатывать около 1-400 000 строк на таблицу. К сожалению, у меня пока нет достаточного опыта в этой области, чтобы самому сделать заключение ...

Большое спасибо!

Ссылка:

Как обрабатывать внешний ключ при разбиении

Разделение таблиц mySQL с внешними ключами?

Ответы [ 2 ]

4 голосов
/ 25 марта 2010

Что ж, если вам нужно разделить таблицу на 400.000 строк, получите другую базу данных, чем MySQL. Шутки в сторону. По современным стандартам любая таблица ниже 1.000.000 строк обычно имеет пренебрежимо малый размер (даже небольшой), если у вас нет индекса и т. Д. И современным стандартам в этом отношении около 10 лет.

1 голос
/ 14 декабря 2010

Что ж, раздел не является хорошим решением для сложной модели данных. Если у вас есть только 2-3 таблицы в зависимости друг от друга, вы можете сделать это, но это не красиво. Каждая таблица должна иметь столбец, определяющий раздел. Затем каждая таблица должна иметь триггер для создания новой таблицы, установки внешнего ключа и ограничения уникальности.

Например, AuditTransaction <- Auditentry </p>

Каждая аудиторская операция имеет от 0 до n аудиторских операций. Таблица audentry содержит внешний ключ транзакции. Обе таблицы должны иметь столбец creationDate, поскольку он используется для разбиения обеих таблиц.

------ создать триггер для вставки аудита в транзакцию

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

----- затем создайте триггер для 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();
...