你能不能给我一个提示,是否有一种简单的方法,使用标准的stl或boost容器来模拟SQL表结构,并能够按多列排序(并且可能有聚簇索引)?例如,用于保存给定表的东西,按类型,颜色,重量排序:
ID Type Color Weight Hex
1 1 NB 3.5 12
2 1 NB 3.5 14
3 1 NB 3.8 03
4 1 PP 4.0 10
5 2 DP 3.5 15
6 2 O 5.0 12
7 2 O 6.0 09
谢谢
答案 0 :(得分:6)
我使用Boost MultiIndex容器。让我起草一个样本:
<强> Live On Coliru 强>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <vector>
enum class color_t { NB, PP, DP, O };
struct Record {
int ID;
int Type;
color_t Color;
double Weight;
uint8_t Hex;
};
namespace bmi = boost::multi_index;
using Table = boost::multi_index_container<
Record,
bmi::indexed_by<
bmi::sequenced<bmi::tag<struct byInsertion> >,
bmi::ordered_unique<bmi::tag<struct byID>, bmi::member<Record, int, &Record::ID> >,
bmi::hashed_non_unique<bmi::tag<struct byType>, bmi::member<Record, int, &Record::Type> >,
bmi::ordered_non_unique<bmi::tag<struct byDetails>,
bmi::composite_key<Record,
bmi::member<Record, color_t, &Record::Color>,
bmi::member<Record, uint8_t, &Record::Hex>,
bmi::member<Record, double, &Record::Weight>
>
>,
bmi::random_access<bmi::tag<struct byCustomRandomAccess> >
>
>;
#include <boost/range/adaptors.hpp> // lazy demo purposes
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <iostream>
using namespace boost::adaptors;
int main() {
auto getId = [](auto& r) { return r.ID; };
auto dump = [](auto&& range) -> auto& {
for (auto&& v:range) std::cout << v << " ";
return std::cout;
};
Table table {
Record { 4, 1, color_t::PP, 4.0, 0x10 },
Record { 3, 1, color_t::NB, 3.8, 0x03 },
Record { 7, 2, color_t::O, 6.0, 0x09 },
Record { 1, 1, color_t::NB, 3.5, 0x12 },
Record { 2, 1, color_t::NB, 3.5, 0x14 },
Record { 5, 2, color_t::DP, 3.5, 0x15 },
Record { 6, 2, color_t::O, 5.0, 0x12 },
};
using namespace boost;
std::cout << "Insertion order: ";
dump(table | transformed(getId)) << "\n";
std::cout << "byID: ";
dump(table.get<byID>() | transformed(getId)) << "\n";
std::cout << "Type 2: ";
dump(
make_iterator_range(table.get<byType>().equal_range(2))
| transformed(getId)) << "\n";
auto& query = table.get<byDetails>();
std::cout << "Color == NB, Hex = [0x00..0x0f]: ";
{
auto lb = query.upper_bound(make_tuple(color_t::NB, 0x00));
auto ub = query.upper_bound(make_tuple(color_t::NB, 0x0f));
dump(make_iterator_range(lb, ub) | transformed(getId)) << "\n";
}
std::cout << "Color == NB: ";
dump(make_iterator_range(query.equal_range(make_tuple(color_t::NB))) | transformed(getId)) << "\n";
// adhoc order:
{
auto& adhoc = table.get<byCustomRandomAccess>();
std::vector<reference_wrapper<Record const>> tmp(adhoc.begin(), adhoc.end());
// random shuffle, e.g.:
std::random_shuffle(tmp.begin(), tmp.end());
// OR: use some crazy order
auto craziness = [](Record const& a, Record const& b)
{ return (a.ID - 10*a.Type) < (b.ID - 10*b.Type); };
sort(tmp, craziness);
// optionally, reflect that order back into the `byCustomRandomAccess` index:
adhoc.rearrange(tmp.begin());
}
std::cout << "Custom order persisted: ";
dump(table.get<byCustomRandomAccess>() | transformed(getId)) << "\n";
}
打印:
Insertion order: 4 3 7 1 2 5 6
byID: 1 2 3 4 5 6 7
Type 2: 6 5 7
Color == NB, Hex = [0x00..0x0f]: 3
Color == NB: 3 1 2
Custom order persisted: 5 6 7 1 2 3 4
答案 1 :(得分:0)
我将std::tuple
用于std::vector
:
using sql_table_1 = std::vector<std::tuple<size_t,size_t,Color,float,size_t>>
为了排序,您使用std::sort
+ costumized比较器排序,例如,让我们根据weight
进行排序:
sql_table_1 table {/*...populate...*/};
using row = std::tuple<size_t,size_t,Color,float,size_t>;
std::sort(table.begin(),table.end(),[](const row& row1, const row& row2){
return std::get<3>(row1) < std::get<3>(row2);
});
答案 2 :(得分:0)
我头脑中的第一个自然方式是使用模板+类。您的班级将保留预定义的字段(例如int ID
,int Type
等)。您可以使用模板参数为您的类重载sort函数,以便您可以调用类似instance.SortBy<field>()
的内容。这将要求您在每次需要不同的类时创建单独的方法和字段集,因此在一段时间后它可能变得相当繁琐,但对于小任务,它可能就足够了。现在使用现有的库可能要容易得多,但如果我对预定义的数据有一些小任务,我可能会选择这个解决方案。