2016-06-20 4 views
1

Я заинтересован в хранении нескольких значений в одном столбце, а не использовать традиционные многие-ко-многим таблице:Как увеличиваем значения ключа от силы два

class Beer 
    include DataMapper::Resource 

    property :id, Serial 
    property :name, String 
    property :containers, Integer # use bit arithmetic to store multiple values 

    validates_presence_of :name, :containers 

end 

class Container 
    include DataMapper::Resource 

    property :id, Serial # increment in powers of two? 
    property :name, String 
    property :volume, Integer 

    validates_presence_of :name, :volume 

end 

Контейнеры:

ID Name Volume Unit 
1 Growler 64  oz 
2 Cowler 32  oz 
4 Bomber 750  mL 
8 Six-fifty 650 mL 
16 4 pack 64  oz 
32 6 pack 72  oz 

Бирс:

ID Name Containers 
1 LSD 72 
2 Düo 16 

есть простой способ настроить DataMapper ресурс для увеличения последовательных значений по степеням о f 2? Я предполагаю, что ассоциация будет сложной задачей.

+1

какая польза может это иметь? –

+0

Еще одна таблица для обслуживания. Побитовые запросы бывают быстрыми и мощными. Тем не менее, мне, вероятно, понадобится вспомогательная функция в представлении, чтобы преобразовать 'Containers' в его строковое представление. – craig

+0

Все это происходит для отказа. Не делай этого. Используйте последовательные номера и правильную реляционную таблицу. Вы идете против зерна здесь самым худшим образом, и это будет постоянная борьба за то, чтобы все было в порядке. Помните, Postgres имеет столбец «ARRAY», а MySQL и Postgres поддерживают «JSON», если вам нужна произвольная структура данных. – tadman

ответ

2

Вы не можете сделать это с Serial типом недвижимости, но вы можете использовать Integer и before :create крюка:

class Container 
    include DataMapper::Resource 

    property :id, Integer, key: true # Use whatever options you like 
    property :name, String 
    property :volume, Integer 

    validates_presence_of :name, :volume 

    # Create a new id based on the last element 
    before :create do |c| 
    last_container = Container.last 
    # If integer has N bits, then you can only store N containers in your database (normally, 32 or 64 bits). 
    c.id = last_container ? (last_container.id * 2) : 1 
    end 
end 

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


О, кстати, если вам нужен быстрый доступ к базе данных, вы должны проверить, посмотреть на Graph databases и neo4jrb, в OGM для Neo4j.

+0

Pretty slick решение. Я, вероятно, поеду на «стандартный» маршрут, как все говорят. – craig

+0

@craig Тогда вы, сэр, поступаете правильно:] – Wikiti