Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Безболезненное удаление сервиса

Короткий доклад о том, как "безболезненно" удалять записи из БД - при этом сохраняя их для последующего использования.

Related Books

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

  • Be the first to like this

Безболезненное удаление сервиса

  1. 1. Безболезненное удаление сервиса Илья Чесноков UK2 Group
  2. 2. Таблица сервисов ● Записи невозможно дублировать из-за составного уникального ключа: – customer_id – entity (обычно – имя домена) – serviceplan_id ● Сервисы нужно как-то удалять ● Хочется сохранить “устаревшие” записи о сервисах ● Данные связанных таблиц тоже хочется сохранить (оплата, конфигурация, история статусов, и т.д.)
  3. 3. Таблицы “*_history” ● Создать таблицу service_history (где нет условия уникальности) и копировать туда сервисы ● Для каждой связанной таблицы создать таблицу с суффиксом _history, и копировать туда “старые” записи
  4. 4. Отдельная БД ● При удалении переносить все данные в отдельную БД – при удалении – или заранее, репликацией нужных таблиц ● Таблица сервисов будет отличатся, их: – переносить “вручную” при удалении – реплицировать, но чтобы они никогда не удалялись
  5. 5. “Прятать” старые сервисы в промежуточном слое ● Moose ↔ DBIx::Class ↔ DBI ↔ MySQL ● Можно переопределить search_rs() в My::DB::ResultSet::Service Fetchers
  6. 6. # Wrapper to exclude services with 'deleted' status from search sub search_rs {     my $self = shift;     # We don't want a recursion here  # so call the next method directly     my $next_method = $self­>next::can('search_rs');     return $self­>$next_method(@_)         ­>$next_method({ status => { '!=' => 'deleted' } }); }
  7. 7. Переопределяем Service resultset ● Использование resultset_attributes() – Ненадежно, может исчезнуть в следующих версиях! ● Переопределить resultset_attributes() в My::DB::Result::Service ● resultset_attributes() не знает о current_source_alias()! ● Можно имитировать в My::DB::ResultSet::Service::new()
  8. 8. sub new {     my $class = shift;     my $self         = $class­>next::method(@_);     my $status_alias = $self­>current_source_alias . '.status';     # Fuck with resultset internals     $self­>{cond} ||= {};     if (!$self­>{cond}­>{$status_alias}) {         $self­>{cond}­>{$status_alias} = { '!=' => 'deleted' };     }     return $self; }
  9. 9. sub new {     my $class = shift;     my $self         = $class­>next::method(@_);     my $status_alias = $self­>current_source_alias . '.status';     # Fuck with resultset internals     $self­>{attrs}­>{where} = $self­>_stack_cond(         $self­>{attrs}­>{where},         { $status_alias => { '!=' => 'deleted' } },     );     $self­>{cond} = $self­>{attrs}­>{where};     return $self; }
  10. 10. Выглядит подозрительно
  11. 11. Но кое-как работает
  12. 12. Один тест не работал ● prefetch + where – where используется в запросах, где есть prefetch, для добавления условий
  13. 13. Написал в рассылку DBIx::Class ● ...и заодно в IRC ● ribasushi был занят :)
  14. 14. В итоге ● Удалили ключ distinct_service – оставили только ограничения в коде ● CREATE VIEW service_v AS SELECT * FROM service WHERE status != 'deleted'; ● My::DB::Result::Service → My::DB::Result::Service::All sub delete { shift­>update({ status => 'deleted' }); 1; } ● My::DB::Result::Service: use parent 'My::DB::Result::Service::All'; __PACKAGE__­>table('service_v') 1;
  15. 15. Спасибо!

    Be the first to comment

    Login to see the comments

Короткий доклад о том, как "безболезненно" удалять записи из БД - при этом сохраняя их для последующего использования.

Views

Total views

459

On Slideshare

0

From embeds

0

Number of embeds

16

Actions

Downloads

1

Shares

0

Comments

0

Likes

0

×