Я хотел лишь сказать, что если я захочу добавить в структуру какое-то поле, например, немного надуманное поле shouldHavePassport пользователю, которое не хранится в БД, а вычисляется в триггере или еще где-нибудь потом как user.age >= 14 или еще и учитывает страну, то будет нелогично не добавлять его в структуру. Его стоит указать несериализуемым, да, но добавлять в структуру просто необходимо, в то время как к базе оно может не иметь никакого отношения.
идеально иллюстрирует вложенный запрос
О, спасибо, теперь я понял что мне напомнила ваша ORM. Текстовое представление regexp'ов
Я думал добавить сырые С-указатели, но этого не будет
Правильно, не надо, мы живем в С++1(4|7)
тут надо подумать
Тут думать не передумать. Посмотрите в строну sequelize. К сожалению, не все их решения можно перевести на С++, но как позаимствовать идеи, синтаксис и некоторые фичи — очень полезно будет
Разумеется, так можно. И нужно делать именно так, если ORM не поддерживает вложенные сущности. Но, согласитесь, хочется спихнуть весь этот (можно сказать служебный и практически ненужный) код на ORM
структуры схеме не соответствуют
Все правильно, они и не должны. Если я хочу добавить transient поле в структуру, я его туда добавлю, но не буду добавлять в make_column. Ну и по-хорошему в структуре пометить их комментарием, что они не сериализуются.
Здесь еще тонкий момент со связями не многие-ко-многим. Придется писать в структуре или experimental::optional<T> или, как в вашем решении std::shared_ptr<T>, что, безусловно, снизит читаемость кода
Тут скорее всего надо еще руками определить `BookCategories` и привязывать не к `&Category::books` а к `&BookCategories::bookId`, но в идеале это делать автоматически.
Пишу «типа такого», потому что если бы у меня было четкое представление как это сделать, я бы это давно уже сделал ;)
Вы немного неправильно меня поняли, я имел в виду связь между книгой и категорией многие-ко-многим (+сущность BookCategory с соответствующими айдишниками) и, соответственно, выдирать категории именно для конкретной книги, к которой они привязаны. Для этого случая ваш код еще больше усложнится и будет еще менее поддерживаемый.
Я понимаю, что пока Вы такие случаи не рассматриваете, но они встречаются очень часто в реальной жизни. Как ORM для несвязанных между собой таблиц получилось неплохо, и, надеюсь, полностью покрывает ваши нужды ;)
Да, Вы все правильно поняли. Это в том числе работает со связями многие-ко-многим и рекурсивно. Например, получить 10 книг, отсортированных по дате создания, у каждой получить по 3 категории, которые не имеют родителя. Это, разумеется, просто сделать руками, но в sequelize-like синтаксисе будет выглядеть примерно так:
Book.findAll({
limit: 10,
order: [['createdAt', 'DESC']],
include: [{
model: Category,
as: 'categories',
limit: 3,
where: {
parentId: null
},
attributes: ['id', 'title'] //Зачем получать лишнюю информацию из базы?
}]
});
Да, понятно, что сделать несложно. Но, в целом, в качестве связей для меня больше важна возможность достать связанные foreign keyем сущности, нежели чем ограничение существования той самой связанной сущности
Просто я тоже искал «идеальную» ORM для с++, но ничего «годного» не нашел. Вы пытаетесь сделать решение, лучшее, чем существующие, и в этом случае без этих фич никуда. Попробовав, например, hibernate для java или sequelize для node.js вряд ли Вы будете делать запросы руками, которые за Вас может сделать ORM, даже если это просто. Я бы с радостью перевел некоторые свои поделки на с++, как на свой первый и «родной» язык, но пока все ORM, на которые я смотрел имеют только лишь недостатки. Select у Вас выглядит, действительно, очень хорошо, но, согласитесь, достаточно узкая специализация получилась, без join'ов, и, как уже указано leschenko group by и select field1, field2… а не select * (и, кстати, offset'а)
Хотелось бы поскорее уже во всю мощь потрогать руками связку vinyl + sql!
А как Вы эффективно сортируете данные по разным полям?
Единственное решение, которое я сейчас вижу(и использую) это создание индексов для всех полей, по которым надо сортировать(+если используется выборка по полю 1, а сортировка нужна по полю 2 или 3, приходится создавать 2 индекса: 1, 2 и 1, 3)
В таком случае получается достаточно много индексов, а также накладывается ограничение, что это поле не может содержать nil
Уже с сентября прошлого года в бете версии 1.7.* tarantool'а, а также есть слухи о тестировании и скором выходе версии 1.8 с поддержкой sql. Насколько будет оправдан переход на эти версии и насколько будет сложна миграция между ними?
А, Вы про то, что в базе написано
categoryId
, а в структуреcategory
, например?Я так и понял, я не понял к чему тогда относился комментарий
Я хотел лишь сказать, что если я захочу добавить в структуру какое-то поле, например, немного надуманное поле
shouldHavePassport
пользователю, которое не хранится в БД, а вычисляется в триггере или еще где-нибудь потом какuser.age >= 14
или еще и учитывает страну, то будет нелогично не добавлять его в структуру. Его стоит указать несериализуемым, да, но добавлять в структуру просто необходимо, в то время как к базе оно может не иметь никакого отношения.О, спасибо, теперь я понял что мне напомнила ваша ORM. Текстовое представление regexp'ов
Правильно, не надо, мы живем в С++1(4|7)
Тут думать не передумать. Посмотрите в строну sequelize. К сожалению, не все их решения можно перевести на С++, но как позаимствовать идеи, синтаксис и некоторые фичи — очень полезно будет
Разумеется, так можно. И нужно делать именно так, если ORM не поддерживает вложенные сущности. Но, согласитесь, хочется спихнуть весь этот (можно сказать служебный и практически ненужный) код на ORM
Все правильно, они и не должны. Если я хочу добавить transient поле в структуру, я его туда добавлю, но не буду добавлять в make_column. Ну и по-хорошему в структуре пометить их комментарием, что они не сериализуются.
Здесь еще тонкий момент со связями не многие-ко-многим. Придется писать в структуре или
experimental::optional<T>
или, как в вашем решенииstd::shared_ptr<T>
, что, безусловно, снизит читаемость кодаИ что-нибудь типа такого в описании:
Тут скорее всего надо еще руками определить `BookCategories` и привязывать не к `&Category::books` а к `&BookCategories::bookId`, но в идеале это делать автоматически.
Пишу «типа такого», потому что если бы у меня было четкое представление как это сделать, я бы это давно уже сделал ;)
Вы все сами уже ниже описали ;)
Ничего хитрее я не имел в виду
Я понимаю, что пока Вы такие случаи не рассматриваете, но они встречаются очень часто в реальной жизни. Как ORM для несвязанных между собой таблиц получилось неплохо, и, надеюсь, полностью покрывает ваши нужды ;)
Просто я тоже искал «идеальную» ORM для с++, но ничего «годного» не нашел. Вы пытаетесь сделать решение, лучшее, чем существующие, и в этом случае без этих фич никуда. Попробовав, например, hibernate для java или sequelize для node.js вряд ли Вы будете делать запросы руками, которые за Вас может сделать ORM, даже если это просто. Я бы с радостью перевел некоторые свои поделки на с++, как на свой первый и «родной» язык, но пока все ORM, на которые я смотрел имеют только лишь недостатки. Select у Вас выглядит, действительно, очень хорошо, но, согласитесь, достаточно узкая специализация получилась, без join'ов, и, как уже указано leschenko group by и select field1, field2… а не select * (и, кстати, offset'а)
Спасибо, сами того не зная, Вы натолкнули, как мне кажется, на правильное решение моей задачи)
А как Вы эффективно сортируете данные по разным полям?
Единственное решение, которое я сейчас вижу(и использую) это создание индексов для всех полей, по которым надо сортировать(+если используется выборка по полю 1, а сортировка нужна по полю 2 или 3, приходится создавать 2 индекса: 1, 2 и 1, 3)
В таком случае получается достаточно много индексов, а также накладывается ограничение, что это поле не может содержать nil