cycle / docs

Cycle ORM Documentation

Home Page:https://cycle-orm.dev/docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add article with comparison to other ORMs

flaksp opened this issue · comments

Add article to the docs that explains difference between this ORM and other popular solutions such as Doctrine and Eloquent.

This is more for the blog post, but I can try to give some explanation here:

Note: I keep editing this answer as more information surfaces, but still, take with a grain of salt.

Eloquent

  • Cycle ORM is DataMapper vs Eloquent is ActiveRecord, it provides the ability to operate with a data source on a different level and isolates persistence functionality (i.e. you can use plain domain objects for your data)
  • Supports database schema introspection and reflection (a.k.a. it can write migrations for you)
  • Automatically join tables when needed (WHERE IN is possible as well), this simplifies filtering by relation and increases the performance in many cases (laravel/framework#8720 laravel/framework#18415), this is possible due to Cycle knows the structure of your database, while Eloquent does not
  • Cycle can work like ActiveRecord, Eloquent can't work like DataMapper
  • Cycle relies on DBAL layer, Eloquent combines DBAL and ORM into one package
  • ORM does not provide support for Polymorphic Many-To-Many relations yet
  • Lazy loading is achieved using proxy objects and references vs callable relations in Laravel
  • Cycle requires schema calculation, while Eloquent can work as a drop-in solution
  • At the moment (Jan 2020) Cycle is outperforming Eloquent by 15%-50% in synthetic benchmarks (https://github.com/adrianmiu/forked-php-orm-benchmark)
  • Cycle can use any collection type for its relation, including Eloquent collections.

Overall Eloquent is a bit different class of ORM, not really comparable to the feature set of Cycle.

Doctrine v2.0+

  • The cycle does not provide an analog of DQL, this part is managed using Query Builders
  • Caching is out of the scope of the ORM and can be supported as an external extension vs support on the core level of Doctrine
  • Cycle currently does support composite PKs (since v2), JTI and STI
  • Doctrine allows you to handle different events via hooks, Cycle allows linking commands together to achieve the same goal (example: create a snapshot after entity change)
  • Cycle can use any collection type - Doctrine, Eloquent, custom or even arrays
  • ORM can be cloned to operate in alternative scope, you can safely have multiple ORM instances
  • Persist exceptions won't break the heap (analog of EntityManager), you can safely retry
  • Cycle persists data using command chains (IDDFS) vs flat sorted persisters (DSF), it allows Cycle to bypass almost all of the Doctrine limitations listed here: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/limitations-and-known-issues.html
  • Cycle's codebase about 8 times smaller (https://scrutinizer-ci.com/g/doctrine/orm/code-structure/master/code-coverage vs https://codecov.io/gh/cycle/orm), though this is mostly due to the absence of DQL and the fact that Cycle extensions (schema, annotations) are not mandatory and it's fairly new
  • ORM makes a hard separation between EntityManager and UoW (Heap + disposable Transactions), it makes possible simpler batch operations, multiple UoW scopes, ActiveRecord-like approach and simplifies testing of the domain layer
  • Cycle can use any data-carrying model (how) vs hard link to unique classes in Doctrine, this allows you to model any type of data from any source (for example KV lists stored in a flat table, entity pointers, composed objects) or use one domain model for multiple repositories.
  • Cycle allows you to configure mapping schema at runtime (fields and relations), it drastically simplifies the development of a whole class of SaaS applications like ERP/CRM/CMS
  • Cycle support eager/lazy-loaded entity embeddings (partial selections) and the ability to select embedding separately from parent entity (no relations in embeddings allowed)
  • You can load related data via JOIN or by external SQL with WHERE IN, ORM will select the most optimal approach automatically (works with nested and cyclic relations); in general Cycle provides more instruments to load and filter related data
  • Cycle does not perform cascade delete on ORM level, it relies on database FKs
  • Cycle provides an ability to control persist strategy (for example incremental changes or a custom set of queries to persist entity), ORM does not support optimistic locking yet while Doctrine does
  • At the moment (Jan 2020) Cycle is outperforming Doctrine by 30%-70% in synthetic benchmarks (https://github.com/adrianmiu/forked-php-orm-benchmark)
  • Cycle can use any collection type for its relation, including Doctrine collections.

Overall, Cycle is relatively small compared to Doctrine and does not have all the features created by all the Doctrine contributors. However, it uses different design principles to represent the entities which, in our opinion, provides greater and easier abilities to model and query datasets. We greatly respect Doctrine, but our use case (long-running application with dynamic database schema) makes hard to use it without a lot of low-level tweaking and dealing with the stateful concept of EM.

commented

Would be nice if you could include a comparison with CakePHP ORM too 🙂.

@ADmad Cake ORM seems nice, but I'm not sure I will be able to allocate time to dig deep into it. So far it looks like it uses the base model for entities, so you can't use for clean domain layers.

Cycle allows you to configure mapping schema at runtime (fields and relations)

where can i read more about it?