<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE article  PUBLIC "-//NLM//DTD Journal Publishing DTD v3.0 20080202//EN" "http://dtd.nlm.nih.gov/publishing/3.0/journalpublishing3.dtd"><article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="3.0" xml:lang="en" article-type="research article"><front><journal-meta><journal-id journal-id-type="publisher-id">OJAppS</journal-id><journal-title-group><journal-title>Open Journal of Applied Sciences</journal-title></journal-title-group><issn pub-type="epub">2165-3917</issn><publisher><publisher-name>Scientific Research Publishing</publisher-name></publisher></journal-meta><article-meta><article-id pub-id-type="doi">10.4236/ojapps.2023.135051</article-id><article-id pub-id-type="publisher-id">OJAppS-124881</article-id><article-categories><subj-group subj-group-type="heading"><subject>Articles</subject></subj-group><subj-group subj-group-type="Discipline-v2"><subject>Biomedical&amp;Life Sciences</subject><subject> Chemistry&amp;Materials Science</subject><subject> Computer Science&amp;Communications</subject><subject> Engineering</subject><subject> Physics&amp;Mathematics</subject></subj-group></article-categories><title-group><article-title>
 
 
  Distributed File System Based on a Relational Database
 
</article-title></title-group><contrib-group><contrib contrib-type="author" xlink:type="simple"><name name-style="western"><surname>Vladyslav</surname><given-names>Kutsman</given-names></name><xref ref-type="aff" rid="aff1"><sub>1</sub></xref></contrib></contrib-group><aff id="aff1"><label>1</label><addr-line>Computer Sciences Department, Information Technologies and Computer Engineering Faculty, Vinnytsia National Technical University, Vinnytsia, Ukraine</addr-line></aff><pub-date pub-type="epub"><day>10</day><month>05</month><year>2023</year></pub-date><volume>13</volume><issue>05</issue><fpage>643</fpage><lpage>658</lpage><history><date date-type="received"><day>25,</day>	<month>March</month>	<year>2023</year></date><date date-type="rev-recd"><day>13,</day>	<month>May</month>	<year>2023</year>	</date><date date-type="accepted"><day>16,</day>	<month>May</month>	<year>2023</year></date></history><permissions><copyright-statement>&#169; Copyright  2014 by authors and Scientific Research Publishing Inc. </copyright-statement><copyright-year>2014</copyright-year><license><license-p>This work is licensed under the Creative Commons Attribution International License (CC BY). http://creativecommons.org/licenses/by/4.0/</license-p></license></permissions><abstract><p>
 
 
  Working with files and the safety of information has always been relevant, especially in financial institutions where the requirements for the safety of information and security are especially important. And in today’s conditions, when an earthquake can destroy the floor of a city in an instant, or when a missile hits an office and all servers turn into scrap metal, the issue of data safety becomes especially important. Also, you can’t put the cost of the software and the convenience of working with files in last place. Especially if an office worker needs to find the necessary information on a client, a financial contract or a company’s financial product in a few seconds. Also, during the operation of computer equipment, failures are possible, and some of them can lead to partial or complete loss of information. In this paper, it is proposed to create another level of abstraction for working with the file system, which will be based on a relational database as a storage of objects and access rights to objects. Also considered are possible protocols for transferring data to other programs that work with files, these can be both small sites and the operating system itself. This article will be especially interesting for financial institutions or companies operating in the banking sector. The purpose of this article is an attempt to introduce another level of abstraction for working with files. A level that is completely abstracted from the storage medium.
 
</p></abstract><kwd-group><kwd>File System</kwd><kwd> PostgreSQL</kwd><kwd> Golang</kwd><kwd> AWS</kwd><kwd> HDD</kwd><kwd> Ldap</kwd><kwd> Active Directory</kwd><kwd> AES Encryption</kwd><kwd> Fintech</kwd><kwd> Banking</kwd></kwd-group></article-meta></front><body><sec id="s1"><title>1. Introduction</title><p>The storage and use of information is a complicated process, since one has to face a large number of tasks that have to be solved in the process of work. For examples information can be stored on a storage with different types of file system like NTFS [<xref ref-type="bibr" rid="scirp.124881-ref1">1</xref>] or FAT [<xref ref-type="bibr" rid="scirp.124881-ref2">2</xref>] also it can be AWS [<xref ref-type="bibr" rid="scirp.124881-ref3">3</xref>] storage and each of these storages has own characteristics, depending of the business requirements. In this article operate with the following entities such as COMPANY—PRODUCT—CLIENT. An example of a company is an insurance company, a bank, a leasing company. As an example of a PRODUCT, as example can be insurance, credit, leasing, respectively by the essence of the client need to understand the final recipient of the financial product.</p><p>Each entity has a specific set of properties. So in the case of a company, this is a certificate, a license, etc. For a product, this is a description of the product itself, for example, if it is a car leasing, then this is the documentation for the subject of leasing itself. In the case of a client, this is a certain set of documents of the client, which ultimately allows to conclude the financial transaction itself. But for a computer and the operating system [<xref ref-type="bibr" rid="scirp.124881-ref4">4</xref>] (hereinafter OS) installed on it, all these entities are a record in the database and a set of files with different sizes and extensions, such as pdf, png, etc. Also, the OS does not know anything about the importance of this or that document. In the same way, it is impossible to guess in advance how much disk space is needed in order to store information. Lets to consider a real case. For example, if you structure the data of the company’s clients by name, where the client’s name is a directory on disk N and subdirectories are a specific set of data on the client, and if the information on the logical disk are placed in the form <xref ref-type="fig" rid="fig1">Figure 1</xref> of a tree.</p><p>Then soon may arise a situation when the disk is full and it will be impossible to create directory for a new client or add files to an existing client directory because this will require transferring data for some client directory to another disk. But transferring data on the John Doe 1 client from one disk to another is not as trivial a task as it might seem at first glance. Since the data for this client is most likely stored in some accounting system in which links to documents are stored, and accordingly, when changing the disk, it will be necessary to change the links in the database of the accounting system. The situation is exactly the same when it is necessary to transfer new clients to another drive, which leads to inconvenience when working with data directly for the company manager. Now let’s simulate a situation where, for some unknown reason, not enough attention is</p><p>paid to data security. And an unwanted user of the company gets access to our N drive, and as a result, he receives all the information on the company’s customers in an open form, downloads what he needs and safely sends the company’s customer base to a competitor. In the same way, it may be necessary to separate information within the client directory into access levels by company departments, for example, only Department1 should have access to the ClientData1 directory, and Department2 and Department3 should have access to ClientData2. That is, to create a client directory in the case of windows, its need at least a bat file that will automatically set the rights to the client directory and subdirectories. And it becomes clear that there are a number of tasks that may not be so obvious at first glance, but they exist and often they have to be solved in completely different ways.</p><p>This article is a description of the key nodes and the general mechanism of a possible abstraction level based on a relational database for working with files and data stores, that is, a kind of distributed file system based on relational database DFSboRD.</p><p>DFSboRD architecture.</p><p>On <xref ref-type="fig" rid="fig2">Figure 2</xref> shows a schematic representation of the main elements of the general architecture of DFSboRD.</p><p>This diagram shows the following key elements:</p><p>1) Physical storage such as NASS, AWS, HDD.</p><p>2) Database DB, within the article the database is implemented on PostgreSQL [<xref ref-type="bibr" rid="scirp.124881-ref5">5</xref>] .</p><p>3) The SB software block that implements protocols for working with files within the article was released in Golang [<xref ref-type="bibr" rid="scirp.124881-ref6">6</xref>] . The following file exchange protocols have also been implemented, such as WebDav [<xref ref-type="bibr" rid="scirp.124881-ref7">7</xref>] , FTP/FTPS [<xref ref-type="bibr" rid="scirp.124881-ref8">8</xref>] [<xref ref-type="bibr" rid="scirp.124881-ref9">9</xref>] , a local implementation of file exchange based on the HTTP(S) protocol [<xref ref-type="bibr" rid="scirp.124881-ref10">10</xref>] [<xref ref-type="bibr" rid="scirp.124881-ref11">11</xref>] .</p><p>4) Admin panel AP is designed for manage the issuance of rights, the creation of logical drives, the generation of connection links, etc.</p><p>One of the main elements in this scheme is the DataBase and the SB software block <xref ref-type="fig" rid="fig2">Figure 2</xref>. For a more detailed consideration, we divide into two corresponding parts.</p></sec><sec id="s2"><title>2. Data Base</title><p>To better understand the idea it is necessary to consider in detail the main objects of the database. For an example, was used descriptions and snapshots of tables from a working database. For convenience, the database objects was divided into two parts, namely the logical part—the part that stores information about the logical structure of disks, directories, files, access rights, tokens and the physical part—these are Tables 1-4 that store data about physical storages.</p><sec id="s2_1"><title>2.1. Logical Part</title><p>Let’s look at the main objects that form the logical part:</p><table-wrap id="table1" ><label><xref ref-type="table" rid="table1">Table 1</xref></label><caption><title> The disc table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (500)—name of the disc</td></tr><tr><td align="center" valign="middle" >Size</td><td align="center" valign="middle" >Bigint—disc size in byte</td></tr></tbody></table></table-wrap><table-wrap id="table2" ><label><xref ref-type="table" rid="table2">Table 2</xref></label><caption><title> The folder_to_disc linking table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Disc_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint PK</td></tr></tbody></table></table-wrap><table-wrap id="table3" ><label><xref ref-type="table" rid="table3">Table 3</xref></label><caption><title> The file_to_disc linking table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Disc_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >File_id</td><td align="center" valign="middle" >Bigint PK</td></tr></tbody></table></table-wrap><table-wrap id="table4" ><label><xref ref-type="table" rid="table4">Table 4</xref></label><caption><title> The folder table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (500)—name of the folder</td></tr><tr><td align="center" valign="middle" >Parent_id</td><td align="center" valign="middle" >Bigint—parent directory identifier</td></tr><tr><td align="center" valign="middle" >Size</td><td align="center" valign="middle" >Bigint—size</td></tr><tr><td align="center" valign="middle" >User_del</td><td align="center" valign="middle" >Bigint—the user who deleted the directory</td></tr><tr><td align="center" valign="middle" >Date_del</td><td align="center" valign="middle" >Timestamp—date when was deleted</td></tr><tr><td align="center" valign="middle" >User_id</td><td align="center" valign="middle" >Bigint—creator</td></tr><tr><td align="center" valign="middle" >Date_create</td><td align="center" valign="middle" >Timestamp—date when was created</td></tr><tr><td align="center" valign="middle" >Mod_time</td><td align="center" valign="middle" >Bigint—date when was modified</td></tr><tr><td align="center" valign="middle" >Perm</td><td align="center" valign="middle" >Smallint—field indicating existing of access control list</td></tr></tbody></table></table-wrap><p><xref ref-type="table" rid="table4">Table 4</xref> has an additional composite index on the fields (Parent_id, Name), this index is used to speed up the search for a child directory if program receive a path as a string, as in the case of WebDAV or FTP protocols. For example, if program have the following string like “John Doe 1/Documents1”, need to split it by the “/” character and, having received an array of strings [John Doe 1, Documents1], program will find out the Id of the “John Doe 1” directory using <xref ref-type="table" rid="table2">Table 2</xref> link table, then program are looking for Id for “Documents1” and in this case need composite index (Parent_id, Name) for the fastest possible selection. In <xref ref-type="table" rid="table4">Table 4</xref> and <xref ref-type="table" rid="table5">Table 5</xref>, there is a Perm field whose value range is [0, 1] where 0 is the Access control list (ACL) to the object are not set and 1 the ACL to the object are set. <xref ref-type="table" rid="table1">Table 1</xref> does not have this field because the disk permissions must be set in advance. And in the case of a directory or a file, the rights can be inherited from the parent object until the Perm field is found in the child element, indicating that this object has its own ACL, which will be inherited by its child elements in the same way. Object File are different then Folder or Disc. The Files object is described using 2 tables: <xref ref-type="table" rid="table5">Table 5</xref> and <xref ref-type="table" rid="table7">Table 7</xref>. <xref ref-type="table" rid="table5">Table 5</xref> describes object File and all his attributes and <xref ref-type="table" rid="table7">Table 7</xref> stores all file’s physical addresses.</p><p><xref ref-type="table" rid="table3">Table 3</xref> and <xref ref-type="table" rid="table6">Table 6</xref> are al linking tables, this tables realise a one-to-many relationship, because one folder and one disc can contains lot of files.</p><table-wrap id="table5" ><label><xref ref-type="table" rid="table5">Table 5</xref></label><caption><title> The file table that stores information about a file</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (500)—name of the file</td></tr><tr><td align="center" valign="middle" >Size</td><td align="center" valign="middle" >Bigint—size</td></tr><tr><td align="center" valign="middle" >Date_ create</td><td align="center" valign="middle" >Timestamp—date when was created</td></tr><tr><td align="center" valign="middle" >Date_del</td><td align="center" valign="middle" >Timestamp—date when was deleted</td></tr><tr><td align="center" valign="middle" >Mime</td><td align="center" valign="middle" >Character varying (500)—mime-type</td></tr><tr><td align="center" valign="middle" >User_id</td><td align="center" valign="middle" >Bigint—creator</td></tr><tr><td align="center" valign="middle" >Mod_time</td><td align="center" valign="middle" >Bigint—date when was modified</td></tr><tr><td align="center" valign="middle" >User_del</td><td align="center" valign="middle" >Bigint—the user who deleted the file</td></tr><tr><td align="center" valign="middle" >Perm</td><td align="center" valign="middle" >Smallint—field indicating existing of ACL</td></tr><tr><td align="center" valign="middle" >Load</td><td align="center" valign="middle" >Smallint—field indicating load stay</td></tr></tbody></table></table-wrap><table-wrap id="table6" ><label><xref ref-type="table" rid="table6">Table 6</xref></label><caption><title> The file_to_folder linking table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >File_id</td><td align="center" valign="middle" >Bigint PK</td></tr></tbody></table></table-wrap><p><xref ref-type="table" rid="table7">Table 7</xref> has File_id, Store_id fields and this is the composite PK where File_id is the identifier of file object and Store_id is the physical store id. That is, one file can have several storage locations at the same time (Store_id), and if the physical storage fails, it just need to switch the program to use another storage block, and all other connected programs work as they did. The second important point here is the Crdec field—indicating in what form the file is in the physical storage in decrypted or encrypted, it will be discussed in detail later.</p><p><xref ref-type="table" rid="table8">Table 8</xref> is used as a bucket, which stores information from which directory or disk this file was deleted from. There is a similar table for the directory object.</p><p><xref ref-type="table" rid="table9">Table 9</xref> contains information about users. <xref ref-type="table" rid="table1">Table 1</xref>0 contains information about user groups. And <xref ref-type="table" rid="table1">Table 1</xref>1 realises one-to-many relationship user to groups.</p><table-wrap id="table7" ><label><xref ref-type="table" rid="table7">Table 7</xref></label><caption><title> The file_to_way table, which stores information about the physical location of a file</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >File_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Store_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Url</td><td align="center" valign="middle" >Character varying (500)—path to the storage file</td></tr><tr><td align="center" valign="middle" >Load</td><td align="center" valign="middle" >Smallint—field indicating load stay</td></tr><tr><td align="center" valign="middle" >Crdec</td><td align="center" valign="middle" >Smallint—field indicating in what form the file is in storage (encrypted or not)</td></tr></tbody></table></table-wrap><table-wrap id="table8" ><label><xref ref-type="table" rid="table8">Table 8</xref></label><caption><title> The file_delete table, which stores information about deleted file</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >File_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Disc_id</td><td align="center" valign="middle" >Bigint</td></tr><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint</td></tr></tbody></table></table-wrap><table-wrap id="table9" ><label><xref ref-type="table" rid="table9">Table 9</xref></label><caption><title> The user table, which stores information about users</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (500)—Full name</td></tr><tr><td align="center" valign="middle" >User_login</td><td align="center" valign="middle" >Character varying (40)—User login</td></tr><tr><td align="center" valign="middle" >Password</td><td align="center" valign="middle" >Character varying (40)—Password encrypted by sha1</td></tr></tbody></table></table-wrap><table-wrap id="table10" ><label><xref ref-type="table" rid="table1">Table 1</xref>0</label><caption><title> The groups table, which stores information about user groups</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (500)—name of the group</td></tr></tbody></table></table-wrap><table-wrap id="table11" ><label><xref ref-type="table" rid="table1">Table 1</xref>1</label><caption><title> The user_to_group linking table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >User_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Group_id</td><td align="center" valign="middle" >Bigint PK</td></tr></tbody></table></table-wrap><p>The final element of the logical part will be the organization of access rights.</p><p>It is suggested to use the following types of access rights:</p><p><xref ref-type="table" rid="table1">Table 1</xref>2 contains basic permissions <xref ref-type="fig" rid="fig3">Figure 3</xref> and <xref ref-type="table" rid="table1">Table 1</xref>3 contains basic permissions groups <xref ref-type="fig" rid="fig4">Figure 4</xref>. <xref ref-type="table" rid="table1">Table 1</xref>4 form permissions to permissions groups <xref ref-type="fig" rid="fig5">Figure 5</xref>. This was made for reasons of database architecture in order to be able to write access rights to an object as a composite PK.</p><p>There are similar tables for folder and file objects.</p><p>An example query with comments explaining permission checking:</p><p>SELECT (CASE WHEN f.perm = 1 THEN f.id ELSE allowed_permid END) INTO allowed_permid FROM folder f</p><p>LEFT JOIN perm_group_folder pgf ON pgf.folder_id = f.id AND pgf.group_id IN (SELECT group_id FROM user_to_group WHERE user_id = inuser_id)</p><p>LEFT JOIN perm_user_folder puf ON puf.folder_id = f.id AND puf.user_id = inuser_id</p><p>LEFT JOIN perm_to_pack ptpg ON ptpg.pack_id = pgf.perm_id AND ptpg.perm_id IN (1, 3)</p><p>LEFT JOIN perm_to_pack ptpu ON ptpu.pack_id = puf.perm_id AND ptpu.perm_id IN (1, 3)</p><p>WHERE f.id = dirid AND (f.perm = 0 OR f.perm = 1 AND (puf.folder_id IS NOT NULL AND</p><p>ptpu.pack_id IS NOT NULL OR puf.folder_id IS NULL AND ptpg.pack_id IS NOT NULL));</p><p>This query checks write permissions ([1, 3] is the id of the permissions table) for user groups ptpg.perm_id IN (1, 3) and user ptpu.perm_id IN (1, 3).</p><p>inuser_id—variable storing the user ID.</p><p>allowed_permid—variable storing the NULL value from beginning.</p><p>This part query “(CASE WHEN f.perm = 1 THEN f.id ELSE allowed_permid END) INTO allowed_permid”—implements inheritance, that is, if the object has a perm value of 1, then the variable allowed_permid gets the value f.id, otherwise the previous value of allowed_permid is used. The link <xref ref-type="table" rid="table1">Table 1</xref>5 and <xref ref-type="table" rid="table1">Table 1</xref>6 are connected via a composite PK, which speeds up the selection as much as possible. This part query “(puf.folder_id IS NOT NULL AND ptpu.pack_id IS NOT NULL OR puf.folder_id IS NULL AND ptpg.pack_id IS NOT NULL)”—first of all, the user’s rights are checked, and then the rights for the user’s groups.</p><p><xref ref-type="table" rid="table1">Table 1</xref>7 contains the following fields of interest to us, such as Token (SHA1) [<xref ref-type="bibr" rid="scirp.124881-ref12">12</xref>] and what object identifiers it is associated with User_id, Disc_id, Folder_id. Also, one of the main conditions is that the Token value must be unique for any</p><table-wrap id="table12" ><label><xref ref-type="table" rid="table1">Table 1</xref>2</label><caption><title> The permissions table storing basic permission codes</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (255)</td></tr><tr><td align="center" valign="middle" >Description</td><td align="center" valign="middle" >Character varying (255)</td></tr></tbody></table></table-wrap><table-wrap id="table13" ><label><xref ref-type="table" rid="table1">Table 1</xref>3</label><caption><title> The perm_pack table represents grouped permissions</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (255)</td></tr><tr><td align="center" valign="middle" >Description</td><td align="center" valign="middle" >Character varying (255)</td></tr></tbody></table></table-wrap><table-wrap id="table14" ><label><xref ref-type="table" rid="table1">Table 1</xref>4</label><caption><title> The perm_to_pack is linking table for perm_pack where perm_id this is Id from permissions and pack_id this is id from perm_pack</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Perm_id</td><td align="center" valign="middle" >Bigint</td></tr><tr><td align="center" valign="middle" >Pack_id</td><td align="center" valign="middle" >Bigint</td></tr></tbody></table></table-wrap><table-wrap id="table15" ><label><xref ref-type="table" rid="table1">Table 1</xref>5</label><caption><title> The perm_user_folder table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >User_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Perm_id</td><td align="center" valign="middle" >Bigint—id of the perm_pack table</td></tr></tbody></table></table-wrap><table-wrap id="table16" ><label><xref ref-type="table" rid="table1">Table 1</xref>6</label><caption><title> The perm_group_folder table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Group_id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Perm_id</td><td align="center" valign="middle" >Bigint—id таблицы perm_pack</td></tr></tbody></table></table-wrap><table-wrap id="table17" ><label><xref ref-type="table" rid="table1">Table 1</xref>7</label><caption><title> The token table holds user access tokens</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Token</td><td align="center" valign="middle" >Character varying (40)—user token</td></tr><tr><td align="center" valign="middle" >User_id</td><td align="center" valign="middle" >Bigint</td></tr><tr><td align="center" valign="middle" >Disc_id</td><td align="center" valign="middle" >Bigint</td></tr><tr><td align="center" valign="middle" >Folder_id</td><td align="center" valign="middle" >Bigint</td></tr><tr><td align="center" valign="middle" >Status</td><td align="center" valign="middle" >Smallint</td></tr><tr><td align="center" valign="middle" >Creator_id</td><td align="center" valign="middle" >Bigint</td></tr></tbody></table></table-wrap><p>of the User_id, Disc_id, Folder_id pairs. For example, in <xref ref-type="fig" rid="fig6">Figure 6</xref>, the highlighted entry under id = 16 says that token=c80d9ba4852b67046bee487bcd9802c0 identifies the user user_id = 175 to access disc_id = 6. And if is necessary make the directory a network disk, then need specify 0 in the disc_id field and specify in the folder_id directory identifier (id) that must be as a network drive. In the future, Token will be used in SB <xref ref-type="fig" rid="fig2">Figure 2</xref> to identify the client when interacting via the WebDav, FTP/FTPS protocols, this will be discussed in more detail later in the SB section.</p></sec><sec id="s2_2"><title>2.2. Physical Part</title><p>Now let’s to consider the implementation of the physical part of the base. But first, let’s look at the structure of the file tree for placing files on physical storage, shown in <xref ref-type="fig" rid="fig7">Figure 7</xref>. At the root of a physical disk, 1000 directories can be placed</p><p>in each directory, there are also 1000 directories and 1000 files in each child directory.</p><p>In the database, this structure is implemented by 4 tables.</p><p><xref ref-type="table" rid="table1">Table 1</xref>8 contains fields such as Url—this is the storage identifier within the operating system; in the case of Windows, it can be either the address of the disk itself or the address of the folder on the disk, for example, it can be Y:\ and Y:\storage\, respectively. Also, this table contains such a field as Crdec—indicating in what form files should be stored on this storage in encrypted or not. DFSboRD uses AES [<xref ref-type="bibr" rid="scirp.124881-ref13">13</xref>] encryption implemented by the golang. Also, this field is in <xref ref-type="table" rid="table7">Table 7</xref>, but in this table it indicates whether the file was encrypted before uploading or, in case of an error, it was not encrypted.</p><p><xref ref-type="table" rid="table1">Table 1</xref>9 provides to implement the structure shown in <xref ref-type="fig" rid="fig7">Figure 7</xref>. The Parent_id field indicates whether this is the root directory or not. Counter—counter of nested directories or files if it is a child directory.</p><p>Using <xref ref-type="table" rid="table2">Table 2</xref>0 and <xref ref-type="table" rid="table2">Table 2</xref>1, physical storage is grouped into blocks. The Status_replica field of the storage_pack indicates whether this block of physical storage is a replica or the main one that the system works with. Only one block can be the main one with which the system is currently working; the other are</p><table-wrap id="table18" ><label><xref ref-type="table" rid="table1">Table 1</xref>8</label><caption><title> The storage_fiz table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (255)—name</td></tr><tr><td align="center" valign="middle" >Size</td><td align="center" valign="middle" >Bigint—size in bytes</td></tr><tr><td align="center" valign="middle" >Allowed_size</td><td align="center" valign="middle" >Bigint—free space in bytes</td></tr><tr><td align="center" valign="middle" >Url</td><td align="center" valign="middle" >Character varying (255)—Storage address</td></tr><tr><td align="center" valign="middle" >Crdec</td><td align="center" valign="middle" >Smallint—a field indicating in what form the files should be stored (encrypted/decrypted)</td></tr></tbody></table></table-wrap><table-wrap id="table19" ><label><xref ref-type="table" rid="table1">Table 1</xref>9</label><caption><title> The storage_folder table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Counter</td><td align="center" valign="middle" >Integer</td></tr><tr><td align="center" valign="middle" >Parent_id</td><td align="center" valign="middle" >Bigint</td></tr></tbody></table></table-wrap><table-wrap id="table20" ><label><xref ref-type="table" rid="table2">Table 2</xref>0</label><caption><title> The storage_pack table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Id</td><td align="center" valign="middle" >Bigint PK</td></tr><tr><td align="center" valign="middle" >Name</td><td align="center" valign="middle" >Character varying (255)</td></tr><tr><td align="center" valign="middle" >Status</td><td align="center" valign="middle" >Smallint</td></tr><tr><td align="center" valign="middle" >Status_replica</td><td align="center" valign="middle" >Smallint</td></tr></tbody></table></table-wrap><table-wrap id="table21" ><label><xref ref-type="table" rid="table2">Table 2</xref>1</label><caption><title> The storage_to_pack_storage linking table</title></caption><table><tbody><thead><tr><th align="center" valign="middle" >Column</th><th align="center" valign="middle" >Description</th></tr></thead><tr><td align="center" valign="middle" >Storage_id</td><td align="center" valign="middle" >Bigint PK—Id of storage_fiz table</td></tr><tr><td align="center" valign="middle" >Pack_id</td><td align="center" valign="middle" >Bigint PK</td></tr></tbody></table></table-wrap><p>used for data replication. Another important point is that in <xref ref-type="table" rid="table7">Table 7</xref>, within the same file object (File_id), physical stores (Store_id) are selected from different blocks. The program first time uploads the file to the storage located in the main block, and then after the replication operation, the system adds an entry to <xref ref-type="table" rid="table7">Table 7</xref> with the storage identifier from other blocks that are replication. And as mentioned earlier, if the storage from the main block fails, the administrator can immediately make one of the replication units the main one, imperceptibly for other programs, and disable the damaged one and deal with the problem.</p></sec></sec><sec id="s3"><title>3. SB</title><p>Software block. In this section, was briefly consider the idea of implementing protocols such as WebDav, FTP/FTPS, HTTP(S) for DFSboRD interaction with the user, taking into account the fact that information such as the logical drive, directories on the disk, files, and their attributes are read directly from the database not from the file system. Also, SB is directly involved in uploading/down-loading files to physical storages. The SB configuration files store the key itself, which is used to encrypt/decrypt data. On <xref ref-type="fig" rid="fig8">Figure 8</xref> shows a direct connection to DFSboRD in the form of a network drive using the WebDav protocol.</p><p>As shown in <xref ref-type="fig" rid="fig8">Figure 8</xref>, the system connects to the storage.domen.com server on port 10111—this port is responsible for the WebDav protocol. What is interesting here is that in the connection string was passing the user token “ert4re3wfgh654rtyhgfr45tre45tre3” which is generated in the AP admin panel in <xref ref-type="fig" rid="fig2">Figure 2</xref> DFSboRD and is unique (<xref ref-type="table" rid="table1">Table 1</xref>7 token) having generated another token, substitute it into the string and already connect to another network drive. Also, this token can be used when connecting to DFSboRD via FTP/FTPS protocols as a login and password.</p><p>When connecting to DFSboRD via FTP, the same domain was used, but placed on a different port, namely 2121 ftp://storage.domen.com:2121 further as shown in Figures 9-11. Entered login credentials and accessed data. Also, to work with data, a small web server was made that operates with the HTTP protocol and a small web page was made for working with data that displays the structure of the file tree. Also, the software block is responsible for encrypting and decrypting files before writing or reading to physical storage. Another important point is that when a user connects to DFSboRD, information about the user is checked in Active Directory using the ldap [<xref ref-type="bibr" rid="scirp.124881-ref14">14</xref>] protocol, and it is checked in which groups the user has been added and checking if he has already been blocked.</p><p>The implementation of the protocols itself in the sense of network interaction remains the same, only the part that is responsible for getting directory/file list and their information get data from database.</p></sec><sec id="s4"><title>4. Discussion</title><p>Creating DFSboRD as an abstraction layer is a completely new approach to working with files. The situation in Ukraine serves as irreproachable proof of this. When, after the massive missile shelling of cities, business began to pull his information infrastructure into the clouds in order to save information. But at the same time, the problem arose of the lack of a solution that would allow this to be done quickly and would meet security requirements. The data had to be uploaded to cloud storage, and this is hundreds of terabytes of data, but also power outages. And when copying data while maintaining access rights, it slows down the process even more. Unlike other file systems, DFSboRD stores all data about logical drives, directories, files and their attributes, access rights in the database (which can have several copies, slave servers). Files can also have several copies as on servers in the office and on cloud storages, it is also very important that files are stored in encrypted form on cloud storages, which is very important for the security policy of banks. And in this case, the transfer of the infrastructure takes several minutes, namely, switching the slave server to the master, then you will need to go to the admin panel and make the main block responsible for storing files on cloud storage (<xref ref-type="table" rid="table2">Table 2</xref>0), and its all, DFSboRD is already working on the clouds.</p><p>Also, DFSboRD easily integrates with the company’s Active Directory, and since the data is stored in the database, it eliminates dependence on the domain.</p><p>The problem with the encoding in the file names is also solved, for example when the file is located in windows OS and has a name in Cyrillic, then when transferring to Linux, a situation may arise when the file names become unreadable, then DFSboRD does not have such problems, because the original file names are stored in the database and physically, files may have other names exclusively in Latin.</p><p>DFSboRD is very easy to maintain for the administrator, it is enough to sometimes check the replication of databases, other work the system will do itself. For exaple if the space on one of the blocks runs out, the administrator will be informed by letter or message in a messenger convenient for him.</p><p>Ease of integration with various CRM systems, to connect you will need a token that can be created in the admin panel and that’s it. Further, after loading file, CRM receives its ID, and if CRM need to receive the file, it is enough to transfer its identifier and get need file, and the problem of safety and availability of free disk space is already being solved on the DFSboRD side.</p><p>DFSboRD is operating system independent and also supports various data transfer protocols which are reliable and time-tested. Also it is cheap, which is often crucial when choosing software. There are no restrictions on the number of employees, the amount of data, and so on.</p></sec><sec id="s5"><title>5. Conclusions</title><p>The advantages of this approach, are the following:</p><p>1) Files can be stored in different places at the same time, but logically it will be 1 file, and if the physical storage fails, it is enough to make one of the replication blocks the main one, imperceptibly for other elements of the enterprise information infrastructure.</p><p>2) Files can be encrypted using a AES encryption method, that is, the file cannot be physically read without prior software decryption, using SB.</p><p>3) Convenience of working with files, the ability to integrate with other systems, since another system will not deal with the safety of the file itself, this is taken over by DFSboRD. Also, for some CRM systems, it is easier to store the Id of the file and receive it via some web server than to bother with storing information, allocating space.</p><p>4) More flexible handling. From the admin panel, you can create all the necessary links, grant rights, create a template for setting rights for directories and subdirectories, etc.</p><p>5) The system does not depend on storage and operation systems. For example, if the files are hosted on AWS and our connection is organized through the rclone utility, then it doesn’t matter to us whether it is possible to issue rights to objects because we have ACLs placed directly in the database.</p><p>6) Several orders of magnitude faster search for file directories by name.</p><p>7) Portability, extensibility, scalability to work with different data transfer protocols.</p><p>The main disadvantage is that without a database it will be impossible to restore the structure of the file tree and their ACL. And this requires appropriate qualifications in the operation and maintenance of the database that will be used. There is also a need a certain amount of RAM, since for AES encryption it is necessary to process the entire file.</p></sec><sec id="s6"><title>Conflicts of Interest</title><p>The author declares no conflicts of interest regarding the publication of this paper.</p></sec><sec id="s7"><title>Cite this paper</title><p>Kutsman, V. (2023) Distributed File System Based on a Relational Database. Open Journal of Applied Sciences, 13, 643-658. https://doi.org/10.4236/ojapps.2023.135051</p></sec></body><back><ref-list><title>References</title><ref id="scirp.124881-ref1"><label>1</label><mixed-citation publication-type="other" xlink:type="simple">(2022) NTFS: Microsoft. https://learn.microsoft.com/en-gb/windows-server/storage/file-server/ntfs-overview</mixed-citation></ref><ref id="scirp.124881-ref2"><label>2</label><mixed-citation publication-type="other" xlink:type="simple">(2022) FAT: Microsoft.https://learn.microsoft.com/en-us/troubleshoot/windows-client/backup-and-storage/fat-hpfs-and-ntfs-file-systems</mixed-citation></ref><ref id="scirp.124881-ref3"><label>3</label><mixed-citation publication-type="other" xlink:type="simple">(2022) AWS.  https://docs.aws.amazon.com/s3/index.html</mixed-citation></ref><ref id="scirp.124881-ref4"><label>4</label><mixed-citation publication-type="other" xlink:type="simple">Andrew, S. (2014) Tanenbaum, Herbert Bos Modern Operating Systems. 4th Edition, Vrije Universiteit Amsterdam, The Netherlands.</mixed-citation></ref><ref id="scirp.124881-ref5"><label>5</label><mixed-citation publication-type="other" xlink:type="simple">(2012) PostgreSQL: Up and Running. 4th Edition, O’Reilly Media, Inc., Newton.</mixed-citation></ref><ref id="scirp.124881-ref6"><label>6</label><mixed-citation publication-type="other" xlink:type="simple">Donovan, A.A.A. and Kernighan, B.W. (2015) The GO Programming Language. Addison-Wesley.</mixed-citation></ref><ref id="scirp.124881-ref7"><label>7</label><mixed-citation publication-type="other" xlink:type="simple">Dusseault, L. (2007) http Extensions for Web Distributed Authoring and Versioning (WebDAV). RFC 4918. https://doi.org/10.17487/rfc4918</mixed-citation></ref><ref id="scirp.124881-ref8"><label>8</label><mixed-citation publication-type="other" xlink:type="simple">Postel, J. (1985) File Transfer Protocol (FTP). RFC 959. https://doi.org/10.17487/rfc0959</mixed-citation></ref><ref id="scirp.124881-ref9"><label>9</label><mixed-citation publication-type="other" xlink:type="simple">Ford-Hutchinson, P. (2005) Securing FTP with TLS. RFC 4217. https://doi.org/10.17487/rfc4217</mixed-citation></ref><ref id="scirp.124881-ref10"><label>10</label><mixed-citation publication-type="other" xlink:type="simple">Fielding, R. (1999) Hypertext Transfer Protocol—http/1.1. RFC 2616. https://doi.org/10.17487/rfc2616</mixed-citation></ref><ref id="scirp.124881-ref11"><label>11</label><mixed-citation publication-type="other" xlink:type="simple">Rescorla, E. (2000) http over TLS. RFC 2818. https://doi.org/10.17487/rfc2818</mixed-citation></ref><ref id="scirp.124881-ref12"><label>12</label><mixed-citation publication-type="other" xlink:type="simple">Rescorla, E. (2011) US Secure Hash Algorithms (SHA and SHA-Based HMAC and HKDF). RFC 6234.</mixed-citation></ref><ref id="scirp.124881-ref13"><label>13</label><mixed-citation publication-type="other" xlink:type="simple">Schaad, J. (2003) Use of the Advanced Encryption Standard (AES) Encryption. RFC 3565. https://doi.org/10.17487/rfc3565</mixed-citation></ref><ref id="scirp.124881-ref14"><label>14</label><mixed-citation publication-type="other" xlink:type="simple">Good, G. (2000) LDAP Data Interchange Format. RFC 2849.</mixed-citation></ref></ref-list></back></article>