Understanding the fundamental trade-offs in distributed systems and how CAP theorem applies to database design