Recently I decided to develop two simple PHP classes. My main motivation was having simple tools to create more readable and maintainable, extendible, lightweight and high performance web applications: The idea that every developer dreams about it. Here are my attempts.
Today, our applications are not simply runs-on-a-LAMP-stack applications if we are facing or expecting high volume requests from clients. No more. We have to think things differently. Sometimes we are facing the problems like it makes us change our data store, caching strategies, searching tools etc.
Anyway, I built applications using this strategy:
- Design schemas for my database;
- Design schemas for caches (be prepared for aggressive caching)
- Design shemas for my search modules.
In the past we used to design only schemas for our databases and store/fetch/search data using only database. Then we needed caching solutions to fetch the data fast. Then we started to use caching technologies like Memcached etc. But the most expensive part of our applications was our search modules and searching strategies, because you can never predict and cache that what user wants to search. Nowadays we use Elasticsearch for that purpose ant it performs perfectly. Some even uses Elasticsearch for main data store but it is not a good idea b/c it’s main purpose performing a good searching operations. Whatever.
Sometimes we store data in more than one data store to beat some performance issues, to protect data integrity, to backup the data easily etc. For example we store the data in SQL, then MongoDB but read only from MongoDB. Nowadays, we also store and fetch the data using Memcached/Redis/Couchbase/Elasticsearch etc.
Good-hearted people developed good plugins that automatically replicate the data stored in one platform to another platform. This is the easy way but it is not always best solution. For example creating too much index types in Elasticsearch is not recommended, so you can’t create index types for your all tables or collections.
So, what it is?
I always approach this kind of things like “we have to solve this manually, I must control that flow.” My approach to design/store/fetch/search data is basically like that:
- Design tables/collections for database
- Design object structure for caching
- Design index types for searching. (Probably one or two index type, not for every table/collections)
- Store the data in SQL (or sometimes first in SQL then MongoDB)
- Store same data in Memcached/Redis/Couchbase
- Create new data from new/updated data for search operations (you may need to include parent, child data or other relational data)
- Store new data for searching operations in Elasticsearch
- Always Fetch the data from Memcached/Redis/Couchbase, avoid SQL or MongoDB etc queries.
- Always perform search on Elasticsearch
- For search results, return only doc ids, not full docs
- Fetch full search result data from Memcached/Redis using this doc ids.
- Never delete data as possible, use soft delete as possible
Because of this kind of things I decided to develop two simple PHP classes: Soupmix and ModelUtils.
ModelUtils will help me to ensure that data will be examined the way I designed it in a model configuration. Validation, sanitation, setting defaults operation will be done by ModelUtils.
Soupmix is an interface to perform CRUD operations to interact database systems using same functions but does not provides an ORM/ODM. If it’s a MongoDB instance, usage of functions will ensure that the data will be stored/fetched using MongoDB configurations, connections and functions. For model operations it will help creating/altering/mapping/dropping tables/collections/Elasticsearch indexes and creating sql/nosql indexes.
Using Soupmix classes one may create her own class that controls data flow using more than one databases. For example creating a new class using exact same function names and arguments, of course there may be small differences for connection configurations, she can store data in MySQL first, then in MongoDB, and fetch data from only MongoDB. Or more advance, creating new class with the same functions but having extra parameters for caching or searching operations, etc.
These two libraries are in active development, and somethings that I mentioned above may not be present in these libraries but will be ASAP.
I hope you got the idea.