Модель данных MySQL для Cassandra Помощь? - PullRequest
2 голосов
/ 18 августа 2011

Я пытаюсь перенести модель RDBMS на Cassandra и с трудом создаю схему.Вот моя модель данных:

CREATE TABLE Domain (
    ID INT NOT NULL PRIMARY KEY,
    DomainName NVARCHAR(74) NOT NULL,
    HasBadWords BIT,
    ...
);
INSERT INTO Domain (DomainName, HasBadWords) VALUES ('domain1.com', 0);
INSERT INTO Domain (DomainName, HasBadWords) VALUES ('domain2.com', 0);

CREATE TABLE ZoneFile (
    ID INT NOT NULL PRIMARY KEY,
    DomainID INT NOT NULL,
    Available BIT NOT NULL,
    Nameservers NVARCHAR(MAX),
    Timestamp DATETIME NOT NULL
);
INSERT INTO ZoneFile (DomainID, Available, Nameservers, Timestamp) VALUES (1, 0, "ns1", '2010-01-01');
INSERT INTO ZoneFile (DomainID, Available, Nameservers, Timestamp) VALUES (2, 0, "ns1", '2010-01-01');
INSERT INTO ZoneFile (DomainID, Available, Nameservers, Timestamp) VALUES (1, 1, "ns2", '2011-01-01');
INSERT INTO ZoneFile (DomainID, Available, Nameservers, Timestamp) VALUES (2, 1, "ns2", '2011-01-01');

CREATE TABLE Backlinks (
    ID INT NOT NULL PRIMARY KEY,
    DomainID INT NOT NULL,
    Backlinks INT NOT NULL,
    Indexed INT NOT NULL,
    Timestamp DATETIME NOT NULL
);
INSERT INTO Backlinks (DomainID, Backlinks, Indexed, Timestamp) VALUES (1, 100, 200, '2010-01-01');
INSERT INTO Backlinks (DomainID, Backlinks, Indexed, Timestamp) VALUES (2, 300, 600, '2010-01-01');
INSERT INTO Backlinks (DomainID, Backlinks, Indexed, Timestamp) VALUES (1, 500, 1000, '2010-01-01');
INSERT INTO Backlinks (DomainID, Backlinks, Indexed, Timestamp) VALUES (2, 600, 1200, '2010-01-01');

Исходя из этого, я пришел к выводу, что, возможно, у меня может быть одно пространство ключей: DomainData.В этом пространстве ключей у меня может быть семейство столбцов под названием «Домен», которое похоже на мою таблицу доменов в sql:

"Domain" : { //ColumnFamily
    "domain1.com" : { "HasBadWords" : 0 }, //SuperColumn
    "domain2.com" : { "HasBadWords" : 0 }  //SuperColumn
}

В следующих таблицах я начинаю путаться.По сути, ZoneFile и обратные ссылки должны хранить историю результатов поиска этих значений для каждого домена.Итак, один домен для многих записей ZoneFile.Для запросов я хочу иметь возможность легко получить «новейшую» запись ZoneFile или данный домен.Мне нужно будет сделать то же самое для обратных ссылок.

Я обдумывал что-то вроде этого и делал поиск диапазона ключа для домена, а затем получал «последнюю» запись, которая должна быть самой новой отметкой времени ...

"ZoneFiles" : { //ColumnFamily
    "domain1.com:2010-01-01 12:00:00.000" : { "Available" : 0, "Nameservers" : "ns1" }, //SuperColumn
    "domain1.com:2011-01-01 12:00:00.000" : { "Available" : 1, "Nameservers" : "ns2" }, //SuperColumn
    "domain2.com:2010-01-01 12:00:00.000" : { "Available" : 0, "Nameservers" : "ns1" }, //SuperColumn
    "domain2.com:2011-01-01 12:00:00.000" : { "Available" : 1, "Nameservers" : "ns2" }  //SuperColumn
}

Я не уверен, что это правильный ответ, комбинация строкового домена и строкового datetime в ключе кажется неправильной.Может ли кто-нибудь указать мне правильное направление?

РЕДАКТИРОВАТЬ:

Предполагая, что я использую:

"ZoneFiles" : {
  "domain1.com" : {
    timestamp1 : "{\"available\":1,\"nameservers\":\"ns1\"}",
    timestamp2 : "{\"available\":1,\"nameservers\":\"ns1\"}",
  }
}

Как я могу запросить список доменовстроки, где самая новая отметка времени старше указанной даты?

1 Ответ

4 голосов
/ 18 августа 2011

Если я правильно понимаю ваш вопрос, единственный запрос, который вы хотите сделать для этой модели, это «пожалуйста, получите мне последний файл зоны или обратные ссылки для данного домена»?

Если это так, я бы сохранилпоследние значения для них в семействе столбцов «Домен», под ключом строки доменов, в отдельных столбцах.Я также буду хранить, когда это последнее значение было обновлено (отметка времени).Каждый раз, когда вы получаете новые значения для информации в файле зоны и обратных ссылках, я просто перезаписываю значение в семействе столбцов «Домен» и обновляю метку времени.

Я предполагаю, что вы также сохраняете эти исторические данные, чтобы вы моглизапросить его, и я предполагаю, что тип запроса будет «показать мне все обновления для данного домена между двумя разами» (это правильно?).Если это так, я бы не стал вручную создавать составной ключ строки, так как это потребует, чтобы вы использовали разделитель, сохраняющий порядок, чтобы получить правильные результаты из get_range_slices.И, как вы, наверное, знаете, балансировка нагрузки с помощью OPP может быть сложной задачей.

Вместо этого я хотел бы, чтобы ключ строки был идентификатором домена, а ключ столбца - меткой времени обновления.Затем вы можете упаковать свои обновления в одно значение (например, с помощью json), использовать супер-столбцы или использовать новые составные ключи в 0.8.Если все сделано так, вы можете использовать get_slice для удовлетворения вашего запроса, и он будет правильно работать со случайным разделителем, значительно упрощая балансировку нагрузки.

Tom Wilkie |Акуну |www.acunu.com |@ tom_wilkie

Ответ на комментарий: «Как я могу запросить список доменов, у которых последний столбец отметки времени в файле зоны старше указанной отметки времени?»

Вы могли бы сделатьдобавив в другое семейство столбцов:

row key: day (or hour, or some other reasonable 'bucketing') 
column key: timestamp of update 
value: domain

... каждый раз, когда вы обновляете файл зоны.Затем, чтобы получить самые последние обновленные домены, начиная с t, выполните:

result = []
for i in day(t) ... day(now):
    result.extend(get_slice(i, range(t, '')))

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

Если эти компромиссы не отображаются 'Если уместно, вы можете посмотреть на интеграцию hadoop и использовать ее для выполнения этого запроса.Или вы можете сделать другой компромисс (использовать OPP или выполнить чтение перед записью, чтобы удалить дубликаты, что будет очень медленным)

...