Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在设计azure表存储数据存储时,我如何改变关系数据库的思维?_C#_Azure_Azure Storage_Azure Table Storage - Fatal编程技术网

C# 在设计azure表存储数据存储时,我如何改变关系数据库的思维?

C# 在设计azure表存储数据存储时,我如何改变关系数据库的思维?,c#,azure,azure-storage,azure-table-storage,C#,Azure,Azure Storage,Azure Table Storage,我已经试着很好地掌握Azure表存储有一段时间了,虽然我大体上了解它是如何工作的,但我真的很难动摇我的关系数据库思维。我通常通过榜样学习得最好,所以我想知道是否有人能帮助我。我将概述如何使用关系数据库解决问题的一个简单设置,有人能帮助我将其转换为使用Azure表存储吗 假设我有一个简单的笔记应用程序,它有用户,每个用户可以有任意多的笔记,每个笔记可以有任意多的用户(所有者或观众)。如果我打算使用关系数据库部署它,我可能会按如下方式部署它: 对于数据库,我将从以下内容开始: CREATE TABL

我已经试着很好地掌握Azure表存储有一段时间了,虽然我大体上了解它是如何工作的,但我真的很难动摇我的关系数据库思维。我通常通过榜样学习得最好,所以我想知道是否有人能帮助我。我将概述如何使用关系数据库解决问题的一个简单设置,有人能帮助我将其转换为使用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和UsersNotes.UserID
以及
Notes.ID和UsersNotes.NoteID
之间设置一个关系,并使用约束来强制引用完整性

对于应用程序,我会让ORM为其中的每一个生成一些具有匹配名称属性的实体,我可能会到此为止:

public class Users
{
    public int ID { get; set; }
    public String Username { get; set; }
}
// and so on and so forth
我意识到这种设计完全依赖于关系数据库,我想要的是一些关于如何改变这种思路来使用Azure表存储或任何其他非关系数据存储技术的建议

为了便于讨论,我们还假设我已经安装了Azure SDK,并且已经使用过它,但是我使用SDK的工作知识是有限的,我不想把重点放在这一点上,而是想知道上面的好解决方案是什么样子的。一个好的起点将有助于使SDK对我有意义,因为我将有一个参考点

为了完整起见,让我们这样说吧

  • 注:首次创建数据时,数据会频繁更改,并随时间逐渐减少
  • 用户将有许多笔记,笔记可能有多个用户(不是并发的,只是查看者)
  • 我希望用户数量相当少(少几百个),但我希望有相当数量的笔记(少几百个,每个用户)
  • 我希望查询最多的
    Username
    ,然后显示用户可以访问的注释
  • 我还希望在查看注释时,向具有该注释访问权限的其他用户显示反向查找

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

用Azure表的说法,对象是一个实体

要使用您的示例,用户将从TableStorage实体派生

Azure表存储不是关系存储。没有连接。但是还有LINQ,一种在各种语言中都支持的查询语言。因此,系统不提供连接操作和引用完整性。开发者必须这样做

一些显著优势:

(1) Azure表可以跨多个存储节点自动扩展以保持性能,即使您要处理数十亿个实体。 (2) 它们被复制了3次 (3) 他们有一个SLA (4) 表服务API与RESTAPI兼容,因此可以从非Microsoft技术访问它们

要允许对象存储在Azure表中,只需从TableStorage实体派生即可

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

下面的代码段忽略(1)分区键(2)行键。但这是你需要担心的。将这两个键视为关系表上的主键

你需要仔细考虑这两个关键点。它们决定性能。因为您只获得一组密钥,所以可能需要保留数据的非规范化副本以获得最佳性能

public class Users : TableStorageEntity { public int ID { get; set; } public String Username { get; set; } } 公共类用户:表存储实体 { 公共int ID{get;set;} 公共字符串用户名{get;set;} } 看看你的手。Azure表既便宜又易于使用。

一些想法

  • 整体考虑不同的实体,避免使用任何规范化技术进一步分解它们
  • 为每个实体提供一个标识符,如果索引打开,将允许精确的键搜索和匹配范围键搜索
  • 根据Azure表存储可扩展性需要,将标识符拆分为2个部分。如何很好地分割是一个单独的主题,但通常在定义明确的自然段之间进行分割就足够了
  • 在您的示例中,这两个实体是User和Note

    用户ID足以唯一标识用户。对用户进行范围搜索可能不是很有用。用户id可以是此处的任何固定长度值

    UserId+NoteId足以唯一标识一个注释。注释id可以类似于日期/时间戳+唯一性GUID。这样一个键与UserId结合将唯一地标识注释,并允许在给定时间段内对所有用户注释或用户注释进行范围搜索

    因此,如果UserId=“ABCD”,NoteId可以是“20120801-00f64829-6044-4fbb-8b4e-ae82ae15096e”

    您可以将这两个实体存储在相同或不同的表中。这里有一些不同的方法

    如果每个实体都有自己的表

    • 对于用户,分区键可以是“ABCD”,行键可以是 实际上,任何东西都可以,您只需在分区键上搜索

    • 或者分区键可以是“AB”,行键可以是“CD”

      以上两种方法都适用于大量用户

    • 或者分区键可以是“*”,行键可以是“ABCD”。这对于一组较小的用户来说非常有效,您可以将用户和注释放在同一个表中

    需要注意

    • 分区键可以是“ABCD”,行键可以是“20120801-00f64829-6044-4fbb-8b4e-ae82ae15096”
      Entity        Partition Key              Row Key            
      User          “U” + UserId      
      Note          “N” + NoteId(Date)         NodeId(GUID)
      User Note     “X“  + UserId              NoteId(Date+GUID)
      Note User     “Y“  + NoteId(Date+GUID)   UserId    
      
      Entity      Partition Key  Row Key             Note  User           
      User        UserId      
      User Note   UserId         NoteId(Date+GUID)   Note          (Contains Note and can query for all notes for a user).
      Note User   NoteId(Date)   NodeId(GUID)              UserId  (Can query for all Users of a note. Join on ‘User Note’ to get note.)  
      
      public class NotesUsers : TableStorageEntity
          {
              public int NoteID { get; set; }
              public int UserID { get; set; }
          }