0

我正在开发具有以下用例的应用程序:

  • 用户上传 csv 文件,这些文件需要在应用程序重启时持久化
  • 需要对 csv 文件中的数据进行查询/排序等
  • 用户在上传文件时指定 csv 文件中的可查询列

目前提出的解决方案是:

  • 对于小文件(更常见),将数据转换为 xml 并将其存储为 LOB 或文件系统中。对于查询,将整个数据吞入内存并使用 XQuery 之类的东西
  • 对于较大的文件,在数据库 (MySQL) 中创建动态表,并在可查询列上创建索引

尽管我们已经对该解决方案进行了原型设计,并且它运行得相当好,但它使我们无法支持更复杂的文件格式,例如 XML 和 JSON。解决方案还有一些更琐碎的问题,我不会讨论。

考虑到 NoSQL 数据库的无模式特性,我认为它们可以用来解决这个问题。不过,我没有使用 NoSQL 的实际经验。我的问题是:

  1. NoSQL 是否非常适合这个用例?
  2. 如果是这样,哪个 NoSQL 数据库?
  3. 我们如何将 csv 文件存储在数据库中(列标题构成键和每行的数据字段构成值的键值对集合?)
  4. 我们如何存储可能具有深度层次结构的 XML/JSON 文件?
  5. 查询/索引和其他性能考虑如何?这与 MySQL 之类的东西相比如何?

感谢您的回复并提前致谢!

示例 csv 文件:

employee_id,name,address  
1234,XXXX,abcabc  
001001,YYY,xyzxyz  
...  

DDL 声明:

CREATE TABLE `employees`(  
  `id` INT(6) NOT NULL AUTO_INCREMENT,  
  `employee_id` VARCHAR(12) NOT NULL,  
  `name` VARCHAR(255),  
  `address` TEXT,  
  PRIMARY KEY (`id`),  
  UNIQUE INDEX `EMPLOYEE_ID` (`employee_id`)  
);  

对于 csv 文件中的每一行

INSERT INTO `employees`  
                (`employee_id`,  
                 `name`,  
                 `address`)  
       VALUES (...);  
4

1 回答 1

2

不是一个完整的答案,但我想我可以在某些方面提供帮助。

对于第 2点,我至少可以给出这个有助于整理 NoSQL 实现的链接。

对于数字 3,使用 SQL 数据库(但也应该适合 NoSQL 系统),我会将每一列和每一行表示为单独的表,并添加第三个表,其中包含列和行的外键,其值为细胞。您会得到一个易于过滤的大表。

对于数字 4,您需要“在表格中表示分层数据”

常见的方法是有一个带有属性的表,以及同一个表的外键,指向父表,例如:

+----+------------+------------+--------+
| id | attribute1 | attribute2 | parent |
+----+------------+------------+--------+
|  0 | potato     | berliner   | NULL   |
| 1  | hello      | jack       | 0      |
| 2  | hello      | frank      | 0      |
| 3  | die        | please     | 1      |
|  4 | no         | thanks     | 1      |
|  5 | okay       | man        | 4      |
|  6 | no         | ideas      | 2      |
|  7 | last       | one        | 2      |
+----+------------+------------+--------+

现在的问题是,如果您想获取元素 1 中的所有子元素,则必须单独查询每个项目以获取其子元素。其他一些操作很难,因为它们需要获取到对象的路径,遍历许多其他对象并进行额外的数据查询。

一种常见的解决方法,也是我使用和喜欢的一种,称为修改的预排序树遍历

使用这种技术,我们需要在数据存储和应用程序之间增加一个额外的层,以便在每次结构更改修改时填充一些额外的列。我们将为每个对象分配三个属性leftrightdepth

和属性将从顶部开始计数每个对象,递归遍历所有树叶leftright

left这是对and的遍历算法的模糊近似right(带有的部分depth很容易猜测,这只是要添加的几行):

  1. 将树根(或第一个树根,如果有很多)left 属性设置为 1
  2. 转到它的第一个(或下一个)孩子。将其left属性设置为最后一个数字加一(此处为 2)
  3. 它有孩子吗?如果是,返回数字 2。如果不是,将其设置right为最后一个数字加一。
  4. 转到下一个孩子,并执行与 2 相同的操作
  5. 如果没有更多的孩子,转到父母的下一个孩子并执行与2中相同的操作

这是一张解释我们得到的结果的图片:

mptt
(来源:narod.ru

现在找到一个对象的所有后代或它的所有祖先真的很容易。这可以通过一个查询来完成,使用leftand right

使用它时重要的是在数据和应用程序之间有一个良好的实现层,处理left,rightdepth属性。在以下情况下必须调整这些字段:

  • 一个对象被删除
  • 添加了一个对象
  • 对象的parent字段被修改

这可以通过使用锁的并行过程来完成。它也可以直接在数据和应用程序之间实现。

有关树木的更多信息,请参阅这些链接:

我个人在使用 NoSQL 的几次 django-nonrel 和 django-mptt 方面取得了不错的成绩。

于 2012-11-09T01:07:46.203 回答