Storing numbers that will be also used as digits I'm new to databases, please help me to figure out the best design to store 8-digit numbers that are going to be used for two purposes:


Statistical analyses of separate digits. For example all 2nd digits across all entries or frequency of appearance of a particular digit etc.
Matching whole number to find if the number is in the database in order to get data from relevant columns.


The usage ratio between these two purposes is expected to be close to 50/50. The initial amount of entries is around 6000, with yearly growing close to 2000 entries. Chosen DMS is MariaDB (MySQL).

I can see the 3 possible ways of implementing this:


Store whole numbers and split them each time via programming languages later (for usage #1).
Make 8 columns and store numbers as separate digits. Concatenate them each time via programming language later (for usage #2).
Store both, the whole numbers and separate digits in 8 columns.


But personally I'm not excited about any of these ideas of mine, so I'm seeking an explanatory advice from you.
Your best solution for this is undoubtedly the use of GENERATED columns (also known as VIRTUAL or COMPUTED columns).

You mention MariaDB - the documentation is available here. The core bit (the syntax) is here:

&lt;type&gt;  [GENERATED ALWAYS]  AS   ( &lt;expression&gt; )
[VIRTUAL | PERSISTENT | STORED]  [UNIQUE] [UNIQUE KEY] [COMMENT &lt;text&gt;]


So, for MariaDB, I constructed the following table here (fiddle):

CREATE TABLE the_code_1
(
  code CHAR(8),
  the_code_location CHAR(1) GENERATED ALWAYS AS (SUBSTR(code, 3, 1)) 
  VIRTUAL COMMENT '3rd character'
);


Then I INSERTED some data:

INSERT INTO the_code_1 (code) VALUES ('12345678');
INSERT INTO the_code_1 (code) VALUES ('87654321');


Note that only 1 field is inserted! Then, I SELECT from that table:

SELECT * FROM the_code_1;


Result:

code    the_code_location
_________________________
12345678                3
87654321                6


Which is the 3rd character in both of those fields!  

The table definition above has VIRTUAL, meaning that it's calculated on the fly. The fiddle also shows the use of the PERSISTENT keyword (in place of VIRTUAL), meaning that the data is physically stored on disk.

This is a fiddle using MySQL 5.7 - the only difference is that in place of the the PERSISTENT keyword, STORED is required. The MySQL syntax is here. This is also interesting:

col_name data_type [GENERATED ALWAYS] AS (expr)
  [VIRTUAL | STORED] [NOT NULL | NULL]  -- Note! no PERSISTENT keyword!
  [UNIQUE [KEY]] [[PRIMARY] KEY]
  [COMMENT 'string']


All in all, depending on your disk versus performance requirements, one of these two options is the way to go - you can do a few tests. Your requirements are minimal so either of the two options should work satisfactorily.