如何在设计azure表存储数据存储区时动摇关系数据库思维?

时间:2012-08-01 20:27:01

标签: c# azure azure-storage azure-table-storage

我一直试图很好地掌握Azure Table存储一段时间,虽然我一般都了解它是如何工作的但我真的很难动摇我的关系数据库思维。我通常以身作则最好的学习,所以我想知道是否有人可以帮助我。我将概述一个简单的设置,说明如何使用关系数据库解决问题,有人可以指导我将其转换为使用Azure表存储吗?

让我们说我有简单的笔记记录应用程序,它有用户,每个用户可以拥有他们想要的尽可能多的笔记,并且每个笔记可以拥有所需数量的用户(所有者或查看者)。如果我要使用关系数据库部署它,我可能会按如下方式部署它:

对于数据库,我会从这样的事情开始:

CREATE TABLE [dbo].[Users](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Username] [nvarchar](20) NOT NULL)

CREATE TABLE [dbo].[UsersNotes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NOT NULL,
    [NoteID] [int] NOT NULL)

CREATE TABLE [dbo].[Notes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [NoteData] [nvarchar](max) NULL)        

然后,我会在Users.ID and UsersNotes.UserIDNotes.ID and UsersNotes.NoteID之间建立关系,并使用约束来强制执行参照完整性。

对于应用程序,我会让一个ORM生成一些具有匹配名称属性的实体,并且我可能会称它为一天:

public class Users
{
    public int ID { get; set; }
    public String Username { get; set; }
}
// and so on and so forth

我意识到这种设计完全依赖于关系数据库,而我正在寻找的是如何动摇这一思路以使用Azure Table存储或任何其他非关系数据存储技术的建议。

让我们假设为了论证我已经安装了Azure SDK,并且已经玩过它,但是我使用SDK的工作知识有限,我宁愿不关注它,而是关注什么对上面的一个很好的解决方案看起来像。一个好的起点将有助于使SDK对我有意义,因为我将有一个参考点。

为了完整起见,我们可以说

  • 注意数据在首次创建时会经常更改,并随着时间逐渐减少
  • 用户会有很多笔记,笔记可能有多个用户(不是并发,只是观看者)
  • 我期待相当少的用户(数百人),但我希望有相当数量的笔记(每位用户数百人)
  • 我希望最多查询Username,然后显示用户有权访问的备注
  • 我还希望在查看笔记时,向其他用户显示该笔记的访问权限,反向查找

2 个答案:

答案 0 :(得分:5)

您可以将Azure表视为对象的集合。

在Azure Table的说法中,对象是一个实体。

要使用您的示例,用户将从TableStorageEntity派生。

Azure表存储不是关系型的。没有连接。但是LINQ是一种支持各种语言的查询语言。因此系统不提供连接操作和参照完整性。开发人员必须这样做。

一些显着优势:

(1)即使您正在处理数十亿个实体,Azure表也会自动扩展到多个存储节点以保持性能。 (2)它们被复制3次 (3)他们带有SLA (4)Table服务API符合REST API,因此可以从非Microsoft技术访问它们。

要允许您的对象存储在Azure表中,您只需从TableStorageEntity派生。

如果您搜索“Microsoft Azure表虚拟实验室”,则可以找到更多信息。

下面的代码段忽略(1)分区键(2)rowkey。但这是你需要担心的事情。可以将两个密钥视为关系表中的主键。

你需要非常仔细地考虑这两个关键。他们决定表现。由于您只获得一组密钥,因此可能需要保留非规范化数据副本以获得最佳性能。

    public class Users : TableStorageEntity
    {
        public int ID { get; set; }
        public String Username { get; set; }
    }

检查手。 Azure表便宜且易于使用。

答案 1 :(得分:1)

为什么UsersNotes有ID?为什么不将UserID,NoteID作为复合主键?

所以三个表各有2个属性。第一个是PartitionKey,第二个是RowKey。

如果您希望在NoteID上查询以获取很多UserID,那么在PartitionKey上搜索第4个表比在RowKey上搜索要快。它通常会更便宜,因为它会减少交易。但是你有加载表的事务。

public class NotesUsers : TableStorageEntity
    {
        public int NoteID { get; set; }
        public int UserID { get; set; }
    }

对于Users表,如果这是常见的查询条件,请使用UserName作为PartitionKey。

ATS中没有声明性的引用完整性。您需要在应用程序中强制执行所有数据关系。两部分复合键。对RowKey的搜索就像扫描(不是搜索)。在PartitionKey上搜索就像搜索一样。

但我会去SQL。如果笔记是某人打字,那么这是一个相对较低的数据量。它是关系数据。