Database Storage (Part II)
Last article about part I, I discussed how to make a disk-oriented architecture, to support databases that are larger than the amount of memory that is available in a single machine. We finished up talking about slotted pages, which is how we're going to organize tuples inside of a page to move things around and pack in as many tuples as possible and reaching end to beginning in tuples and beginning to end slot array until there is not space. This is not the only way (but the primary way!!) that the database system is organized.
We can also do log-structured file organization. Instead of storing the full tuple inside of the pages, we just store the information on how that tuple was created or modified. We can also have a log records, which just allow fast sequential writes, as compared to random access.
Sometimes when you read you need to see where to go back unless you compact the log, or build indexes to allow it to jump to location in the log, or you can convert things back in the tuple form (HBASE, Cassandra, etc).
The databases represent pages, and we can break the heap file into pages, and we want to represent data, and how do we store the metadata about the tables, and finally understand storage.
At a high-level a tuple is a sequence of bytes, and it's the job of the database management system to interpret those bytes into attribute types and values, and the catalogs contain the schema information about tables the system uses to figure out the table's interrupt.
We represent data for fixed-length things, what we represent in C/C++ which is the IEEE 754 standard, which is the specification of how to represent numbers in CPUs (bits, big endian/little endian, two;s complement, etc.).
There's a C/C++ representation in terms of INTEGER/BIGINT/SMALLINT/TINYINT and IEEE standard for FLOAT/REAL and VARCHAR/VAR/TEXT/BLOB as header with length and TIME/DATE/TIMESTAMP for the Unix epoch.
Variable precision numbers sounds like what we want to use, because it's fast. But the problem is there might very well be rounding errors.
#include <stdio.h>
int main(int argc, char* argv[]) {
float x = 0.1;
float y = 0.2;
printf("x + y = %.20f\n", x + y);
printf("0.3 = %.20f\n", 0.3);
}
Here are the corresponding outputs when you specify to 20 bits:
You start to care about rounding error if there is a bank account, or if you're trying to send something to space. There's fixed precision numbers. The way/idea to do this is to store the value as a VARCHAR and let the metadata to say the decimal/scope/rounding information. POSTGRES also can run parallel queries. If you want to deal with rounding, the same queries will be extra slow as a result, we can try to cast things as a decimal, etc. Oracle will give you the fixed-point decimal no matter what. Oracle says if the size doesn't fit in the number of character, then it rounds it from you automatically. We can also round to a precision in MYSQL syntax.
Postgres has a syntax for approximating the digits. Here it is:
typedef unsigned char NumericDigit;
typedef struct {
int ndigits; number of digits
int weight; weight of first digit
int scale; scale factor
int sign; positive/negative
NumericDigit *digits; referencing the type, digit storage
} numeric;
The source code is basically a bunch of switch statements, and we're executing this code for every single time we compute this number.
We use a fixed-point decimal if we don't want to lose data using inprecision.
The size of the data is going to be fixed for most database managment systems. What do we do if the thing that we're trying to store doesn't fit in a single page? We'll just have a pointer to some other overflow page that has the data that we want. If we now have a query, we'll have to follow this pointer, copy the data out, and produce it as an output to chain them all together and produce the output that we're looking for.
We can also store things in a filepath or a filepath on a local disk instead of just a external file. You can't manipulate what's in this file. You can read it, but you can't manipulate it. Ephemeral means reading the data and immediately discarding it. The BLOB type indicates a system that stores a really large value in the ephemeral file.
You don't want to store the video in a database. Django, NodeJs, etc. have built in ways to store data outside of a database, for images and other things. There is no rule in how big a file should be. Overflow is transparent to the application, you don't know. In Oracle, this is a BFILE data type and for Microsoft, this is a FILESTREAM data type. This is in the case if the database storage is super expensive.
Let's talk about how to figure out what our tuples look like. The DBMS stores the metadata about the database as well as user permissions and security stuff, so it basically stores the metadata of the databases. Every single DBMS is going to store their catalog inside itself, like eating your own dog food. You don't want to write SQL queries inside of the table. You usually have some C++ code/whatever your data system is programmed in to access a catalog.
Most systems exposes the catalog to the standard information API. In ANSI and SQL they specify INFORMATION_SCHEMA that has the metadata about the tables, and they don't always expose the exact same information about these tables. We are converting commands to get schema:
Postgres -d gets the list of all tables and -d+ gets more information and tells what the metadata of each table will look like.
You need to realize that the relational model doesn't say anything about how we actually want to store data, doesn't know about types, byte-on-byte array, or any of that stuff. So, so far in the class, it's hard to visualize databases. The revisions table is where we updates of the article, and the reference to the usuers and the pageid that represents the articles that we will change.
Now we want to aggregate things together based on the login with the GROUPBY clause. So we want to get the number of employees that log in per month.
So basically what people do is you have these frontend systems with MYSQL/Mongo and stream the data to a backend warehouse and you prune out the data, especially when you know that you don't need it anymore.
















Comments
Post a Comment