草庐IT

mongodb - 在 Mongodb 中嵌入或引用

coder 2023-10-29 原文

我正在开发一个小型应用程序,用于存储有关用户、帐户和交易的信息。用户将拥有许多账户(可能少于 10 个)并且这些账户将有许多交易(可能是 1000 个)。阅读文档似乎表明嵌入如下是要走的路......

{
"username": "joe",
"accounts": [
    {
        "name": "account1",
        "transactions": [
            {
                "date": "2013-08-06",
                "desc": "transaction1",
                "amount": "123.45"
            },
            {
                "date": "2013-08-07",
                "desc": "transaction2",
                "amount": "123.45"
            },
            {
                "date": "2013-08-08",
                "desc": "transaction3",
                "amount": "123.45"
            }
        ]
    },
    {
        "name": "account2",
        "transactions": [
            {
                "date": "2013-08-06",
                "desc": "transaction1",
                "amount": "123.45"
            },
            {
                "date": "2013-08-07",
                "desc": "transaction2",
                "amount": "123.45"
            },
            {
                "date": "2013-08-08",
                "desc": "transaction3",
                "amount": "123.45"
            }
        ]
    }
 ]
}

我的问题是...由于文档中的事务列表将增长到大约 1000 个,数据会变得零散并降低性能。我最好有一个文件来存储用户和不会增长得那么大的帐户,然后有一个单独的集合来存储引用到帐户的交易。或者,还有更好的方法?

最佳答案

这不是要走的路。你有很多交易,你不知道你会得到多少。取而代之的是,您应该像这样存储它们:

{
    "username": "joe",
    "name": "account1",
    "date": "2013-08-06",
    "desc": "transaction1",
    "amount": "123.45"
},
{
    "username": "joe",
    "name": "account1",
    "date": "2013-08-07",
    "desc": "transaction2",
    "amount": "123.45"
},
{
    "username": "joe",
    "name": "account1",
    "date": "2013-08-08",
    "desc": "transaction3",
    "amount": "123.45"
},
{
    "username": "joe",
    "name": "account2",
    "date": "2013-08-06",
    "desc": "transaction1",
    "amount": "123.45"
},
{
    "username": "joe",
    "name": "account2",
    "date": "2013-08-07",
    "desc": "transaction2",
    "amount": "123.45"
},
{
    "username": "joe",
    "name": "account2",
    "date": "2013-08-08",
    "desc": "transaction3",
    "amount": "123.45"
}

在像 MongoDB 这样的 NoSQL 数据库中,你不应该害怕去规范化。正如您所注意到的,我什至没有为用户创建一个单独的集合而烦恼。如果您的用户有更多您必须在每笔交易中显示的信息,您可能需要考虑也包含该信息。

如果您需要搜索或选择这些字段中的任何一个,请不要忘记创建索引,例如:

// look up all transactions for an account
db.transactions.ensureIndex( { username: 1, name: 1 } ); 

和:

// look up all transactions for "2013-08-06"
db.transactions.ensureIndex( { date: 1 } ); 

等等

复制数据有很多优点。使用上面的模式,您可以拥有尽可能多的事务,并且您永远不会得到任何碎片,因为文档永远不会改变 - 您只会添加它们。这也提高了写入性能,并使执行其他查询变得更加容易。

备选

另一种方法可能是将用户名/名称存储在一个集合中,并且只将其 ID 用于交易:

帐户:

{
    "username": "joe",
    "name": "account1",
    "account_id": 42,
}

交易:

{
    "account_id": 42,
    "date": "2013-08-06",
    "desc": "transaction1",
    "amount": "123.45"
},

这会创建更小的交易文档,但这确实意味着您必须执行两次查询才能同时获取用户信息。

关于mongodb - 在 Mongodb 中嵌入或引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18081317/

有关mongodb - 在 Mongodb 中嵌入或引用的更多相关文章

  1. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  2. ruby - Chef LW 资源属性默认值如何引用另一个属性? - 2

    我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我

  3. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  4. ruby - 引用具有指定索引的枚举器值 - 2

    假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum

  5. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  6. Ruby 泄露的对象被 RubyVm::Env 引用 - 2

    我正在跟踪我们的应用程序(ruby2.1)中的内存泄漏问题。我正在使用这两种技术:ObjectSpace.dump_all将所有对象转储到JSON流,然后进行离线分析。我使用的第二种技术是使用ObjectSpace.reachable_objects_from进行实时分析。在这两种方式中,我发现我泄漏的对象被一个对象RubyVM::Env引用。任何人都可以向我解释什么是RubyVM::Env。如何删除这些引用? 最佳答案 RubyVM::Env是一个包含变量引用的内部ruby​​类。这是我的测试:require'objspace'a

  7. ruby - 方法如何引用运算符。 : work? - 2

    这个问题不是很有用因为themethodreferenceoperatorwasremovedfromRuby2.7.0发布前。由于历史原因,这个问题被搁置了。Ruby2.7.0-preview1引入了方法引用运算符.:作为实验性功能。(更多here和here)。有一些抽象示例可用于说明如何使用这个新运算符:method=42.:to_s=>#method.receiver=>42method.name=>:to_smethod.call=>"42"和:method=File.:read=>#method.call('/Users/foo/.zshrc')=>"exportZSH=$H

  8. ruby 认为我在引用一个顶级常量,即使我指定了完整的命名空间 - 2

    在我的应用程序中我有classUserincludeUser::FooendUser::Foo定义在app/models/user/foo.rb现在我正在使用一个定义了自己的Foo类的库。我收到此错误:warning:toplevelconstantFooreferencedbyUser::FooUser仅引用具有完整路径的Foo,User::Foo,而Foo实际上从来没有指的是Foo。这是怎么回事?更新:才想起我之前遇到过同样的问题,在问题1中看到这里:HowdoIrefertoasubmodule's"fullpath"inruby? 最佳答案

  9. ruby - 维基引用API? - 2

    我想通过JSON获取Wikiquote页面的结构化版本(基本上我需要所有短语)示例:http://en.wikiquote.org/wiki/Fight_Club_(film)我试过:http://en.wikiquote.org/w/api.php?format=xml&action=parse&page=Fight_Club_(film)&prop=text但我得到了所有HTML源代码。我需要每个pharse作为数组的一个元素我如何使用DBPEDIA实现这一目标? 最佳答案 首先,我不确定您是否可以使用DBpedia查询wiki

  10. ruby-on-rails - 有没有办法在带有 rails 的 yaml 中引用常量? - 2

    有没有办法让我的en.yml文件包含一个常量?#en.ymlfoo:bar:IloveBAZsomuch!#initializers/constants.rbBAZ="stackoverflow.com"I18n.t("foo.bar")->"Ilovestackoverflow.comsomuch!"?如果没有,有没有办法自己引用yaml文件?foo:bar:Ilove*baz*somuch!baz:stackoverflow.comI18n.t("foo.bar")->"Ilovestackoverflow.comsomuch!" 最佳答案

随机推荐