This post originates from some discussions and conversations I have had and overheard in the last couple of months. It’s about storage and the fact that people have forgotten how much data a Gigabyte can actually hold. In particular, this is related to the storage restriction of the new Oracle Database 18c Express Edition, which limits user data to a maximum of 12 GB. Some people have raised concerns that 12 GB is not a lot of data; others have outright proclaimed that 12 GB is nothing at all to store information. In these days where we stream movies with 10 GB in size and more over the internet and are not even thinking twice about it, 12 GB may not sound like a lot. In reality, however, I would argue that 12 GB can hold quite a bit of information. The data inside a movie is hard to see, and it is even harder to compare with the data that runs our day-to-day lives. How much data is produced by an ATM withdrawal? A phone call? The smart meters inside our homes? The “giga” in Gigabyte comes after the “mega”, which comes after the “kilo”. The “tera” and “peta” come after the “giga”. The “exa”, “zetta”, and “yotta” are something we have not yet gotten to, a matter of time only, for sure. But what does it mean? What is a Gigabyte, what is a Byte, and how much information can actually be stored in them?
Table of Contents
The Byte and its meaning
A Byte is practically the universal unit of information in computer systems used around the world. It consists of 8 Bits, which are 8 binary numbers that can only present two states, 0 and 1.
1 Byte = 8 Bits
If 1 Bit can only hold two states, how much can 1 Byte then hold? The 8 Bits represent the positions for the first 8 values of the power of 2: 20, 21, 22, 23, 24, 25, 26, 27
These equate to:
| Power of 2 Exponent | Decimal value |
|---|---|
| 20 | 1 |
| 21 | 2 |
| 22 | 4 |
| 23 | 8 |
| 24 | 16 |
| 25 | 32 |
| 26 | 64 |
| 27 | 128 |
When adding all of these values up, you get: 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = 255
Considering that 0 also represents a value, you can store up to 256 (0 – 255) different values in 1 given Byte. Depending on which Bit(s) in the Byte are set, you get a certain decimal value:
| 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | Decimal value |
|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 3 |
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 4 |
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 64 |
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 65 |
| 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 78 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 128 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 192 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 255 |
Having 256 different values is already more than enough to represent the English alphabet, consisting of only 26 letters, with 1 Byte, for example. Each letter gets assigned a specific value, which translates to certain Bits set to 1 in a Byte. To differentiate between uppercase and lowercase letters, another 26 values are used within the Byte to represent these, using up a total of 52 values within the Byte. This leaves plenty of more values to represent symbols and also common keyboard control keys, such as [Ctrl], [Shift] and so forth. This method is known as the ASCII table, short for American Standard Code for Information Interchange.
Just like characters, numbers can also be represented within a Byte. A single Byte can store numbers from 0 to 255. If the number that should be stored exceeds 255, a second Byte is needed. When a second Byte is added, there are 8 additional Bits available to represent another 8 values of the power of 2:
Byte 1 (20, 21, 22, 23, 24, 25, 26, 27), Byte 2 (28, 29, 210, 211, 212, 213, 214, 215)
The value table now looks as follows:
| Power of 2 Exponent | Decimal value |
|---|---|
| 20 | 1 |
| 21 | 2 |
| 22 | 4 |
| 23 | 8 |
| 24 | 16 |
| 25 | 32 |
| 26 | 64 |
| 27 | 128 |
| 28 | 256 |
| 29 | 512 |
| 210 | 1,024 |
| 211 | 2,048 |
| 212 | 4,096 |
| 213 | 8,192 |
| 214 | 16,384 |
| 215 | 32,768 |
When adding all of these up, you get: 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 + 32768 = 65535
Again, when considering that 0 also represents a value, it means that 2 bytes can store up to 65,536 different values. When that is not enough, adding a third Byte brings the total number of values that can be represented up to 16,777,216, a fourth Byte up to 2,147,483,647, and so on. This is the basic foundation of how all data types and structures consume one or many bytes to represent the data within.
Multiples of bytes
In today’s world, we store a lot of information, so much that we go way beyond what a couple of bytes can represent. Therefore, the number of bytes required to store information has become rather long. So long that instead of saying something like “8 billion and 230 million bytes” we tend to use the term Gigabytes instead, i.e., 8.23 GB. The word giga itself originates from the Greek language, meaning giant, and represents 1 billion bytes. Before that, we have Megabytes, representing 1 million bytes, and Kilobytes, representing 1 thousand bytes. Both words also originate from the Greek language, megas meaning great and kilo meaning thousand. If you are accustomed to the metric system, kilo makes a lot of sense to you already. We use a Kilogram to express 1,000 Grams, a Kilometer to express 1,000 Meters.
These Greek words are not, as you might think, just made up randomly because someone likes the Greek language. They are actually official metric prefixes (SI prefixes) standardized by the International System of Units (SI). And right now we have up to “yotta” available to us, meaning a million billion billion bytes, or in numbers:
1 000 000 000 000 000 000 000 000
Update November 2025: Meanwhile we also have “ronna” (1027) and “quetta” (1030)
In today’s world, we are still far away from having to deal with Yottabytes of data, nor do we have a convenient way to store them yet. However, it was once for Gigabytes, and yet they are common these days, just as common as Terabytes are. The day will certainly come when Yottabytes are just as common; it’s only a question of when, not if. Here is what the table for multiples of bytes looks like:
| Bytes | Unit Symbol | Unit | Translation (for fun) |
|---|---|---|---|
| 1000 | KB | Kilobytes | thousand bytes |
| 10002 | MB | Megabytes | great bytes |
| 10003 | GB | Gigabytes | giant bytes |
| 10004 | TB | Terabytes | monster bytes |
| 10005 | PB | Petabytes | five bytes (fifth power of 1000) |
| 10006 | EB | Exabytes | six bytes (sixth power of 1000) |
| 10007 | ZB | Zettabytes | seven bytes (Latin derived – seventh power of 1000) |
| 10008 | YB | Yottabytes | eight bytes (eighth power of 1000) |
As you can see, the International System of Units ran out of creativity after Terabytes. But then “monster bytes” is hard to top. 🙂
What can I do with 12 GB of data?
After a long but hopefully useful introduction to the Byte and the multiples of bytes – I certainly enjoyed writing it – now to the actual question: what can you do with 12 GB of data in a database? You know by now that 12 GB equates to 12,000,000,000 bytes or 12 billion bytes. If one were to write an essay on a computer where one byte represents a character, the person can write up to 12 billion characters before running out of disk space. But perhaps let’s look at some more practical examples closer to our day-to-day lives.
Bank account transactions
Bank account transactions themselves are straightforward. They consist of an account number, a timestamp when the transaction occurred, some description of what the transaction was, and, of course, the amount of money going in or out. When you look at the transactions in your own bank account, you will probably see something very similar to this. In the relational world, this can be modeled by a table with 4 columns, looking something like this:
CREATE TABLE transactions
(
account_id NUMBER,
tms DATE,
description VARCHAR2(255),
amount NUMBER
);
When loading such a table with random data, I managed to load more than 180 million such transactions into the table before I hit the 12 GB limit:
SELECT COUNT(*) FROM transactions;
COUNT(*)
----------
180100000
SQL> SELECT * FROM transactions FETCH FIRST 1 ROW ONLY;
ACCOUNT_ID TMS DESCRIPTION AMOUNT
---------- --------- ------------------------------------- ------
4421325 02-OCT-18 Some transaction on your bank account 142
When you do the math, you will find that 180 million transactions equate to just under 500k transactions per day in a 365-day year.
GPS coordinates
GPS coordinates, expressed in Decimal Degrees (DD), are another data set that is really simple. It comprises just two numbers, the latitude and the longitude coordinates, where the values are bound to ±90° for the latitude and ±180° for the longitude, respectively. A value with up to 6 decimal places gets you into the Centimeter (cm) range. This data can be modeled by a table with two numeric columns:
CREATE TABLE gps_coordinates
(
latitude NUMBER(8,6),
longitude NUMBER(9,6)
);
When loading such a table with random coordinates, I managed to load more than 635 million of them into the table before hitting the 12 GB limit:
SQL> SELECT COUNT(*) FROM gps_coordinates;
COUNT(*)
----------
635188908
SQL> SELECT * FROM gps_coordinates FETCH FIRST 1 ROW ONLY;
LATITUDE LONGITUDE
---------- ----------
-83.95285 174.19146
Of course, 635 million coordinates mean 635 million distinct locations within the Centimeter range on our planet, that’s quite a lot and quite precise.
Smart meter data
Smart meters usually also use straightforward formats consisting of a customer ID, a meter ID, the timestamp, and a value. This can be modeled with a relatively simple table consisting of 3 numbers and one timestamp column, but let’s get a bit more creative. Instead of just a number, let’s use a UUID, which takes 32 bytes to represent the string, for both the customer ID and meter ID:
CREATE TABLE meter_readings
(
customer_id VARCHAR2(32),
meter_id VARCHAR2(32),
timestamp TIMESTAMP,
value NUMBER
);
When loading such a table with random smart meter data, I managed to load more than 117 million meter readings into the table before hitting the 12 GB limit:
SQL> SELECT COUNT(*) FROM meter_readings;
COUNT(*)
----------
117155165
SQL> SELECT * FROM meter_readings FETCH FIRST 1 ROW ONLY;
CUSTOMER_ID METER_ID TIMESTAMP VALUE
-------------------------------- -------------------------------- ---------------------------- ----------
44259515664203ABE063D202000A4A51 44259515664303ABE063D202000A4A51 02-NOV-18 01.09.30.000000 PM 18002.8417
Let’s assume that a meter produces a value every 1 minute and a house has 30 smart meters. Based on these numbers, 12 GB can store meter readings for that house for 2,708 days.
Conclusion
12 GB may not seem very impressive in today’s world, where a single movie file can easily consume that amount of data; however, for some of the world’s most important data, it is more than enough to store a significant amount of it.