Как заставить ActiveRecord работать с устаревшими многораздельными / разделенными базами данных / таблицами? - PullRequest
3 голосов
/ 02 ноября 2009

спасибо за ваше время в первую очередь ... после всех поисков в google, github и здесь, и я запутался в громких словах (partition / shard / fedorate) figure Я полагаю, что мне нужно описать конкретную проблему, с которой я столкнулся и спросить вокруг.

Базы данных моей компании работают с массовыми пользователями и заказами, поэтому мы разделяем базы данных и таблицы различными способами, некоторые из них описаны ниже:

way             database and table name      shard by (maybe it's should be called partitioned by?)
YZ.X            db_YZ.tb_X                   order serial number last three digits
YYYYMMDD.       db_YYYYMMDD.tb               date
YYYYMM.DD       db_YYYYMM.tb_ DD             date too

Основная концепция заключается в том, что базы данных и таблицы разделены в соответствии с полем (не обязательно первичным ключом), и существует слишком много баз данных и слишком много таблиц, так что для записи или магического генерирования одной конфигурации database.yml для каждой базы данных и одна модель для каждой таблицы невозможна или, по крайней мере, не лучшее решение.

Я изучил волшебные решения drnic, datafabric и даже исходный код активной записи, возможно, я мог бы использовать ERB для генерации database.yml и установить соединение с базой данных вокруг фильтра, и, возможно, я мог бы использовать named_scope для динамического решения имя таблицы для поиска, но операции обновления / создания ограничены «self.class.quoted_table_name», так что я не мог легко решить мою проблему. И даже я мог бы сгенерировать одну модель для каждой таблицы, потому что ее количество до 30 самое большее.

Но это не СУХОЙ!

Мне нужно чистое решение, подобное следующему DSL:

class Order < ActiveRecord::Base
   shard_by :order_serialno do |key|
      [get_db_config_by(key), #because some or all of the databaes might share the same machine in a regular way or can be configed by a hash of regex, and it can also be a const
       get_db_name_by(key), 
       get_tb_name_by(key),        
      ]
   end
end

Кто-нибудь может меня просветить? Любая помощь будет принята с благодарностью ~~~~

Ответы [ 3 ]

1 голос
/ 04 ноября 2009

Похоже, в этом случае вы должны рассмотреть не использовать SQL.

Если наборы данных настолько велики и могут быть выражены в виде пар ключ / значение (с небольшой ненормализацией), вам следует изучить couchDB или другие решения noSQL. Эти решения являются быстрыми, полностью масштабируемыми и основаны на REST, поэтому их легко наращивать, создавать резервные копии и реплицировать.

Мы все решили все наши проблемы одним и тем же инструментом (поверьте, я тоже стараюсь).

Было бы гораздо проще перейти на решение noSQL, чем переписывать activeRecord.

1 голос
/ 13 октября 2011

Второй случай (где меняется только имя БД) довольно легко реализовать с помощью DbCharmer . Вам нужно создать свой собственный метод шардинга в DbCharmer, который будет возвращать хэш параметров соединения на основе ключа.

Другие два случая не поддерживаются сразу, но могут быть легко добавлены в вашу систему:

  1. Вы реализуете метод шардинга, который знает, как обращаться с именами баз данных в вашей изолированной базе данных, это даст вам возможность делать shard_for(key) вызовы вашей модели для переключения соединения БД.

  2. Вы добавляете метод, подобный этому:

    class MyModel < ActiveRecord::Base
      db_magic :sharded => { :sharded_connection => :my_sharding_method }
    
      def switch_shard(key)
        set_table_name(table_for_key(key))  # switch table
        shard_for(key)                      # switch connection
      end
    end
    
  3. Теперь вы можете использовать свою модель так:

    MyModel.switch_shard(key).first
    MyModel.switch_shard(key).count
    

    и, учитывая, что вы получили shard_for(key) результаты вызова, возвращенные методом switch_shard, вы можете использовать его следующим образом:

    m = MyModel.switch_shard(key) # Switch connection and get a connection proxy
    m.first                       # Call any AR methods on the proxy
    m.count 
    
1 голос
/ 04 ноября 2009

Если вы хотите этот конкретный DSL или что-то, что соответствует логике прежнего шардинга, вам нужно будет покопаться в ActiveRecord и написать гем, чтобы дать вам такую ​​возможность. Все существующие решения, которые вы упоминаете, не обязательно были написаны с учетом вашей ситуации. Возможно, вам удастся согнуть любое количество решений по своей воле, но, в конце концов, вам, вероятно, придется написать собственный код, чтобы получить то, что вы ищете.

...