# lec1 

## Databases introduction

First off why do we even need a database and what do they accomplish?

Generally a databse will have 3 core elements to it:

1. querying
	* Finding things
		* Just as well structured data makes querying easier 

2. access control 
	* who can access which data segments and what they can do with that data 
		* reading, writing, sending, etc

3. corruption prevention
	* mirroring/raid/parity checking/checksums/etc as some examples 

## Modeling Data

Just like other data problems we can choose what model we use to deal with data.
In the case for sqlite3 the main data model we have are tables, where we store our pertinent data, and later we'll learn even data about our data is stored in tables.

Because everything goes into a table, it means we also have to have a plan for _how_ we want to lay out our data in the table.
The __schema__ is that design/structure for our databse.
The __instance__ is the occurance of that schema with some data inside the fields, i.e. we have a table sitting somewhere in the databse which follows the given structure of a aforemention schema.

__Queries__ are typically known to be declarative; typically we don't care about what goes on behind the scenes in practice since by this point we are assuming we have tools we trust and know to be somewhat efficient.

Finally we have __transactions__ which are a set of operations who are not designed to only commit if they are completed successfully.
Transactions are not alllowed to fail. 
If _anything_ fails then everything should be undone and the state should revert to previous state.
This is useful because if we are, for example, transferring money to another account we want to make sure that the exchange happens seamlessly otherwise we should back out of the operation altogether.

