草庐IT

php - MongoDB 模式设计。得不到我想要的

coder 2023-10-30 原文

我认为我的音乐应用程序架构设计有问题。

我有 3 个集合:ArtistsTracksAlbums。 和 3 个类别:artistsalbumstracks

来自艺术家的文档:

         [_id] => MongoId Object
            (
                [$id] => 4ee5bbfd615c219a07000000
            )
        [freeze] => false,
        [genres] => Array,
        [hits] => 0,
        [name] => Sarya Al Sawas,
        [pictures] => Array,

来自相册的文件:

        [_id] => MongoId Object
            (
                [$id] => 4ee88308615c218128000000
            )

        [name] => Sabia
        [slug] => wafiq-habib-ft-sarya-al-sawas-sabia
        [year] => 1999
        [genres] => Array,
        [pictures] => Array,
        [artists] => Array
            (
                [0] => MongoId Object
                    (
                        [$id] => 4ee34a3b615c21b624010000
                    )

                [1] => MongoId Object
                    (
                        [$id] => 4ee5bbfd615c219a07000000
                    )

            )

来自 tracks 的文档

            [_id] => MongoId Object
            (
                [$id] => 4ee8a056615c21542a000000
            )

        [name] => Bid Ashok
        [slug] => wafiq-habib-ft-sarya-al-sawas-bid-ashok
        [genres] => Array,
        [file] => /m/tracks/t.4ee8a05540c624.04707814.mp3,
        [freeze] => false,
        [hits] => 0,
        [duration] => 303,
        [albums] => Array
            (
                [0] => MongoId Object
                    (
                        [$id] => 4ee5cbc3615c216509000000
                    )

            )

        [artists] => Array
            (
                [0] => MongoId Object
                    (
                        [$id] => 4ee5bbfd615c219a07000000
                    )

                [1] => MongoId Object
                    (
                        [$id] => 4ee34a3b615c21b624010000
                    )

            )

首先是良好的模式设计??! 由于多对多关系,我以这种方式设计了这个模式 有时轨道有 2 位艺术家,专辑有 2 位艺术家。

无论如何,我在查询附加到特定轨道的专辑时遇到问题。

假设我在艺术家页面上

  1. 我需要获取所有艺术家专辑和轨道,所以我这样做:

    $cursors = array(
        'albums' => $this->albums->find(array('artists' => $artist->_id))->sort(array('_id' => -1)),
        'tracks' => $this->tracks->find(array('artists' => $artist->_id))->sort(array('_id' => -1)),
        'clips'  => $this->clips->find(array('artists' => $artist->_id))->sort(array('_id' => -1))
    );
    foreach($cursors as $key => $cursor) {
        foreach($cursor as $obj) {
            $obj['name'] = ($this->lang->get() != 'ar' ? $obj['translated']['name'] : $obj['name']);
            $obj['by']   = $this->artists()->get($obj['artists'])->toString('ft');
            ${$key}[]    = $obj;
        }
    }
    
  2. 我需要循环播放所有轨道并获取他们的专辑名称假设这位艺术家有 3000 首轨道 我认为它会很慢....

所以我的问题是:这是一个好的模式设计吗

最佳答案

嗯,这是一个关系性很强的问题,使用非关系数据库来解决这样的问题需要一些努力。总的来说,我认为你的模式设计很好。

您所描述的称为“N+1 问题”,因为您必须对 N 个对象进行 N+1 次查询(在您的情况下,它更复杂,但我想您明白了)。

一些补救措施:

  • 您可以使用 $in运算符查找例如某个艺术家的所有轨道:

    db.tracks.find({"artists" : { $in : [artist_id_1, artist_id_2, ...] } });
    

    如果艺术家的数量变得庞大,这将不起作用,但几百个,也许一千个应该可以正常工作。确保 artists 已编入索引。

  • 您可以对一些经常需要的信息进行反规范化。例如,您可能希望经常显示轨道列表,因此将艺术家的名字复制到每个轨道是有意义的。非规范化主要取决于您从最终用户的角度试图实现的目标。您可能不想完整存储每个艺术家的名字,而是只存储前 50 个字符,因为 UI 无论如何都不会在概览中显示更多内容。

    事实上,您已经对一些数据进行了非规范化,例如专辑中的艺术家 ID(这是多余的,因为您也可以通过轨道获取它们)。这使得查询更容易,但它会更重写。更新很难看,因为您必须确保它们在系统中传播。

  • 在某些情况下,在客户端 (!) 而不是服务器上“加入”可能更有意义。这并不能很好地解决您的问题,但值得注意:假设您有一个 friend 列表。现在服务器必须在显示每个 friend 的名字时查找他们。相反,它可以为您提供一个查找表 ids/friends,而服务器只提供 ids。一些 JavaScript 可以用客户端缓存中的真实姓名替换 ID。

关于php - MongoDB 模式设计。得不到我想要的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8505850/

有关php - MongoDB 模式设计。得不到我想要的的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  6. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  9. ruby-on-rails - 找不到 gem railties (>= 0.a) (Gem::GemNotFoundException) - 2

    我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby​​2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10

  10. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

随机推荐