What's the difference between CRUD and CRUDL? What's the difference between CRUD and CRUDL? database database

What's the difference between CRUD and CRUDL?


I have never seen a definitive definition of what "list" means in a CRUD context, but I have implemented quite a few systems that uses a CRUD approach. Here's some items you might consider for separating "list" operations from "read" operations:

  • Additional searching/filtering parameters (while "read" typically returns one or all items of a kind)
  • List methods may return "shallow" objects for faster access (where objects from "read" methods are large/expensive)
  • Pagination (as you already mention)
  • Some might even consider all methods returning multiple objects "list" operations (where "read" operations return only one item)

But I have to agree with you. None of these fundamentally change the way you interact with the system. It's basically still reading data, perhaps just a little smarter.


For simplicity:

  • READ gets an object.
  • LIST queries a list of IDs for which you can later READ the underlying object or not.

Social network web example

For example, say you operate a social network website.

Imagine that and each User object is like 10 or 20kB long, as you have there tons of things (lists of friends, last searches, albums and photos listings, cookies, last visited pages, list of posts, list of likes, etc).

Imagine also that you have a route and controller that shows a user's profile getting data from the model and injecting it into a view. Let's call it the profile-page-view.

It is obvious that the controller must get all the data in order to pass it to the view renderer.

Imagine that in the profile-page-view you have a friends-widget showing the user's 100-most active friends, and imagine too that you're gonna use all that information (cannot query a partial set of info) to display in each specific user-miniwidget links, posts, photos, etc.

Instead of getting 100 users at a time, which is 10k x 100 users = 1MB of information retrieved from the database, you may opt just to LIST the profiles's most active friends, getting the IDs and not the objects.

And then have the controller to READ only the first 5 of the list (50kB of handled info) spitting them to the HTML.

Then read the other 95 via a sequence of AJAX calls... for example:

  • the users 11 to 50 queried in blocks of 5, triggering the first "5 object-READ operations" 2 seconds after the page load, and each subsequent block 1 second after the previous one has returned, up to user 50 in the list.
  • the remaining ones (50 to 100) only triggered if the browser scrolls to that area or the mouse moves near by.

This is an example where LIST and READ are completely separated.

Model API example

Imagine the API of a model of a system to help companies to sell more. This calculates a set of data over products.

An invoice has lines, and each line has a product associated.

To get the product of the 3rd line of the invoice 4444 you could do:

// Pseudo-language.InvoiceManager invoiceManager;Invoice invoice;InvoiceLine line;Product product;invoiceManager = whateverDependencyInjectionSystemYouUse.getService( "InvoiceManager" );invoice = invoiceManager.getInvoiceById( 4444 );line = invoice.lines[ 3 ];product = line.getProduct();

This performs a READ operation on the product. If it is lazy-loaded, the READ is performed on the line.getProduct(); line of code.

Nevertheless if you want to see the top-sellers of a certain product family, maybe you do not need to "load" all the products in RAM.

Say you want to display the details of the 20 top-selling of the product category "Flowers":

// Pseudo-language.ProductManager productManager;ProductFamily productFamily;Products products;Product product;productManager = whateverDependencyInjectionSystemYouUse.getService( "ProductManager" );productFamily = productManager.getProductFamilyByName( "Flowers" );products = productFamilies.getAllProductsSortedByAmountSoldLastMonth()max = 20;ctr = 0;foreach( product in products ){    dump( p );    ctr++;    if( ctr >= max )    {        break;    }}

In this case, the productFamily.getAllProductsSortedByAmountSoldLastMonth() method would implement a LIST reading at most, but no way would load the real objects inside. What if that category had 1 million flower products in it?!?!?! - That would be a suicide!

Then each iteration on the products.getItem() -implicit call in each iteration of the for-each loop-, the real READ would be performed to query the real object.

In short

Normally in LIST you get IDs you can manage and store super easily in a lightweight manner to later READ the objects behind or not.