繁体   English   中英

我应该使用什么数据结构来建模数据库/表?

[英]What data structure should I use to model a database/table?

数据库通常看起来像这样

┃Name|Age|..┃
┠────┼───┼──┨
┃John│025│..┃
┃Carl│033│..┃
┃....│...│..┃

在这种情况下,我的意思是一个具有固定列大小和可变大小的未排序行的表,可以通过 id 来寻址。

C++11(或更早版本)中是否有可以表示这样的数据的数据结构?

我想了几种方法来欺骗这样的结构,但没有一个是完美的。

1. 分离std::vector

std::vector<std::string> name;
std::vector<unsigned int> age;

// Write
name.push_back("John");
age.push_back(25);

// Read
std::cout << "The first entry is (" << name[0] << " | " << age[0] << ")\n";

但是,定义一个包含许多列的表需要大量标记,并且通过在每个std::vector上调用push_back来写入它真的很乏味。

2. std std::tuplestd::vector

(在这种情况下std::pair就足够了)

std::vector<std::tuple<std::string, unsigned int>> table;

// Write
table.push_back(std::make_tuple("John", 25));

// Read 1
std::string name;
unsigned int age;
std::tie(name, age) = table[0];
std::cout << "The first entry is (" << name << " | " << age << ")\n";

// Read 2
enum
{
    NAME = 0,
    AGE
}
std::cout << "The first entry is (" << std::get<NAME>(table[0]) << " | "
<< std::get<AGE>(table[0]) << ")\n";

(对不起,如果我在这里搞砸了;我从昨天就知道std::tuple的存在)

这很好,但是从它读取需要大量标记,这一次,当您必须定义要放入值的新变量时。您可以将std::tie与您需要值的任何变量执行,但这变得不可读。 第二种方法几乎是完美的,但在 C++11 中我不想使用隐式枚举。

3. std::vectorstd::array

enum
{
    NAME = 0,
    AGE
}

std::vector<std::array<std::string, 2> table;

// Write
table.push_back({"John", "25"});

// Read
std::cout << "The first entry is (" << table[0][NAME] << " | " << table[0][AGE] << ")\n";

这也相当不错,但它遇到了与 2.2 相同的问题。 这也只允许std::string值。 不过,作为交换,它提供了更短、更好的语法。

我建议使用std::vector<Record>来​​保存您的记录。

使用std::map<key, vector_index>作为记录的索引。 这将使您能够通过不同的搜索条件访问记录,而无需一直对向量进行排序。

您没有考虑的一件事是使用某种关联数组的std::vector ,即std::mapstd::unordered_map

这将允许您使用数据库列名称检查向量(或其他顺序容器)中的给定项目

item["Name"]
item["Age"]

等等。 显然,您必须使用变体或类似boost::any的值。

如果您希望与 C++ 中的数据库对话,并在编译时知道列的类型(正如您从建议中看到的那样),那么可能值得考虑直接从数据库 scehema 为您生成具有适当结构的代码的方法. 这里这里已经有几个关于这个主题的问题。 如果 db 值为空怎么办?

由于这个问题在 5 年后仍然存在,我将用从那时起 5 年的编程经验自己回答。

使用std::arraystd::tuple来表示一行是没有意义的。 结构更具表现力并且样板更少。

该问题基本上询问了 AOS(结构数组)、SOA(数组结构)和哈希映射之间的区别。 两者之间的选择取决于您要对数据做什么以及有多少数据。

数据在迭代数据时通过自动缓存预加载加载 64 字节的缓存行。 由于哈希映射是不连续的,因此无法利用缓存机制,因此仅当基于它们的键访问单个条目而不是遍历整个数据集时才应该首选它。

AOS 和 SOA 之间的选择取决于列是单独迭代还是一起迭代。 单独迭代时,通过使用 SOA,我们可以通过不查看其他数组来在缓存行上容纳更多相同的数据。 对于 AOS 和 SOA,更可取的数据结构是std::vector ,它是一个简单的连续数据结构,因此处理器有大量信息用于动态优化。

#-------------------------------------------
#Try with this piece of code based on <map>
#-------------------------------------------    
#include <iostream>
#include <map>
using namespace std;
//---
class myBook
{
public:
    string ISBN;
    string Title;
    int Pages;

    myBook();
    myBook(const myBook &);
    ~myBook(){};
    myBook &operator=(const myBook &pTr);
    int operator==(const myBook &pTr) const;
    int operator<(const myBook &pTr) const;
};

myBook::myBook()
{
    ISBN = "";
    Title = "";
    Pages = 0;
}


myBook::myBook(const myBook &copyin)
{
    ISBN = copyin.ISBN;
    Title = copyin.Title;
    Pages = copyin.Pages;
}


ostream &operator<<(ostream &output, const myBook &myBook)
{
    output << myBook.ISBN << ':' << myBook.Title << ':' << myBook.Pages << std::endl;
    return(output);
}


myBook& myBook::operator=(const myBook &pTr)
{
    this->ISBN = pTr.ISBN;
    this->Title = pTr.Title;
    this->Pages = pTr.Pages;
    return(*this);
}


int myBook::operator==(const myBook &pTr) const
{
    if( this->ISBN != pTr.ISBN) return(0);
    if( this->Title != pTr.Title) return(0);
    if( this->Pages != pTr.Pages) return(0);
    return(1);
   }

//---------------------------
main()
{
    map<string, myBook> BooksLibrary;
    myBook book1;
    //---
    book1.ISBN="1243954-23";
    book1.Title="Autobiography by Ben Franklin";
    book1.Pages=432;
    BooksLibrary["0001"] = book1;
    //---
    book1.ISBN="555-USA991";
    book1.Title="I Robot by Isac Asimov";
    book1.Pages=323;
    BooksLibrary["0002"] = book1;
    //---
    for( map<string, myBook>::iterator ii=BooksLibrary.begin();     ii!=BooksLibrary.end(); ii++)
    {
        std::cout << (*ii).first << "|" << (*ii).second << endl;
    }
    //---
    return(0);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM