DB Reference books. Examples on MUMPS (Caché Object Script)

  • Tutorial
On a hub you can often find various articles on how this or that is done, with direct implementation, code, examples, justifications (even if controversial). Someone puts an example of control , someone gives practical advice on javascript . However, I did not see anyone talking about the organization of the database structure. It does not go beyond any school examples (if I am mistaken, correct and give links). No, SQL vs NoSQL holivars don't interest me. In my humble opinion, the DBMS is secondary in the organization of the database. Performance issues of specific DBMSs become relevant not immediately. Whatever DBMS is chosen, for a specific task, there is only one requirement for performance - performance must be sufficient. And here are the ways to achieve this sufficiency, ways to conveniently and beautifully place the data - to quickly and easily retrieve it, organizing directories and indexes, input and output, ways to scale and / or change the structure of the database throughout life, the methods used, solved and unresolved problems , useful recipes and tips - this is all that I want to talk about.

The development of database structures is a very interesting and non-trivial process. In this vast area there are few living examples that can be seen, discussed. Are you database developers always clear what and how to do? Let's share knowledge, let's ask, tell, discuss, find out. What is the difference between a table or an object or a global - it is important what meaning is embedded, what kind of connections are built, by what means these connections are realized.

A couple of days ago a translation was published in which my approach to database programming was called extreme - I do not quite agree with this. In the comments, there were at least three people (@Ogoun uaoleg 4dmonster ) who said that they would be interested to look at the live use of MUMPS and find out why they should not be afraid of globals. For these people and all those who are interested in discussing the topics I have touched, I am writing this article.


Definition:


The reference book is a slowly changing list of unique positions, containing brief and accurate information of a scientific, industrial or applied nature, united by a single topic . For example, address directories (countries, cities, streets ...) I added “slowly changing” to the definition of Wikipedia .

Requirements:


Basic requirements provided to the directory:
  • The retrieve operation should be fast.
  • The name of any directory item can be changed in one place, and this change will apply throughout the system.

Consider in more detail:

Quickly get the name of the directory element - means do not search . That is, simply read in a known place and give out. This suggests that slowly changing information is accessed frequently. The answer must be issued quickly. How this is done in Caché I will show later. If there is some specialized search there (to find all cities with the letter A removed from the city N by no more than x km) - you can still afford to eat processor time - then issuing the name of the directory item is not.

Changing the name of a directory item in one place means that the updateName operation, in terms of complexity and runtime, is similar to the retrieve operation, except when a new name is validated. But even in this case, no rebuilding and reindexing of large data sets that use this directory element is required. This logically follows from one simple feature of any directories and data in general - there may be errors in the names. That is, you can design to develop and launch a system of any degree of complexity and need, and after some time, it turns out that a mistake has been made in the name. You need to fix this error. You do not want to check and reindex for a long time all or most of your system to fix this error. You do not want the old / new analytical / operational reports or statistics to cease to be consistent with each other due to a change in one name. You do not want to regenerate seo and other page templates on your site. You want to change one name in one place and forget about it. Of course, most of the database developers, probably this is my requirement, will seem obvious, and not worthy of such a large number of letters. But it turned out, in practice, it is performed much less often than one might imagine.

Test
Let's do a simple test. Those of you who have your own site (it is not necessary that it belongs to you, it can just be the site of your company, or your client, to which you have access and can make changes on it) try now, in one place, change the name any directory item (e.g. city). For example, St. Petersburg - rename it to Peter , or Kiev - to the Mother of Russian citiesor something else into something. Can you do this in one place? Has the tag value changed across all pages of your site? Are the addresses of all your pages unchanged? Did the headings and meta descriptions of the linked pages change automatically? No, I do not consider here complex systems of the parser, replacement of word endings and other things. Caching is also not considered for simplicity. ( Poll below ).

Additional requirements provided to the directory:


  • It is necessary to be able to store the names of the directory elements in various languages, while observing the previous requirements. The retrieve operation for any new language should also be performed quickly.
  • It is necessary to keep a history of changes in the elements of the directory (names, structural positions, and other characteristics) with the ability to track and provide information depending on time t (as this city was called yesterday, or t years ago).

These requirements are called additional because they are not important and necessary for all databases. For example, not everyone needs the ability to store element names in different languages. However, even if your site is tailored to one specific language or region, do not rush to delete this functionality from the list of requirements - it may also be useful to you. The urls of some pages contain the Latin name of certain elements of the directory. If this is a name, each time it will be generated based on the reference name - then with updateName - you can get a new URL for the old page, only because of a correction of the error in the name.

Example
The example.com directory contains an item named Kiev . All examples related to this city and site are on the page example.com/kiev meaning kiev - it was received by simple transliteration + lowercase translation. Now, suppose you change the name of a directory item to the Mother of Russian Cities . Since your page is tied to translate the name of the element and the name has changed, the transliteration itself is changing, the address of the page example.com/mat_gorodov_russkih is changing.
These problems can be avoided by setting the name of the directory element in several languages. Let the first be ru and the second partUri. Then when you change the name in one language, it will not automatically change in another (at least this can be controlled). And the page address will remain the same.

Storing the history of changes in directory elements is a functionality that is not always required; it is implemented a little more complicated than multilingualism or name change. This functionality entails an increase in the time required to change the directory item. However, with proper implementation, this time increases slightly. Also, based on the fact that the directory is slowly changing information, there is nothing wrong with a longer change in an element.

Implementation


Let all the directory entries are stored in the ^ Dictionary global

A global is a global variable whose changes are saved to disk. Variable indices appear in parentheses after the variable name, separated by commas. For example:
^ Global Variable ("index1", "index2", ..., "indexN") = "value"
Indices and values ​​are quoted only if they are not numbers. Another variable may also be an index (more on this later).

Assume that the global indexes ^ Dictionary will mean the following:
  1. ontology (rough classification of directories) - our ontology Vehicle (vehicles)
  2. directory name - TransmissionType (type of transmission)
  3. identifier of a directory element (moreover, all identifiers are unique, even within different directories and ontologies)
  4. item version number (0-current current version, the rest is history)
  5. item property name

The name of the global and the meaning invested in each index were invented by me (the developer). I will give a description of these independent rules later (possibly in the following articles). At the moment, we just look at how a simple one-level directory can be organized, without any nesting and other things. The data in the example is taken from a real live database in use. The zw command displays the values ​​of a variable (global or local) with all defined indices. We will execute commands in the terminal. MONTOLOGY> this is the namespace name (defined and coined by me earlier). We display the information in our directory - execute the command:
zw ^ Dictionary ("Vehicle", "TransmissionType") and look at the result:
MONTOLOGY>zw ^Dictionary("Vehicle","TransmissionType")
^Dictionary("Vehicle","TransmissionType",1,0,"UpdateTime")="62086,66625"
^Dictionary("Vehicle","TransmissionType",1,0,"uid")=888
^Dictionary("Vehicle","TransmissionType",2,0,"UpdateTime")="62086,66625"
^Dictionary("Vehicle","TransmissionType",2,0,"uid")=888
MONTOLOGY>

Let's take a close look at what we have deduced. So we printed all the elements of the TransmissionType directory of the ontology of the Vehicle . As you can see in this directory there are only two elements with identifiers 1 and 2 . It is also obvious that since the 4th index is only 0 , then all the elements of this directory are relevant, and after adding, they have never changed (there is no history). Each directory entry has only two properties: UpdateTime (date and time of update in Caché format) and uid (identifier of the user who made the change). Once again, pay attention to the almost complete absence of service words and characters in the team and the result.

As we see in our directory, something important is missing - namely, the names. Let the names of all the elements of all directories in all languages ​​be stored in the ^ NameDictionaryElement global.

Let us assume that the indices of the ^ NameDictionaryElement global will mean the following:
  1. directory item identifier
  2. tongue
  3. name version number (0-current current version, the rest is history)
  4. property name (we will only use updateTime)

We display information on the names of the elements that interest us - we execute the command:
zw ^ NameDictionaryElement (1), ^ NameDictionaryElement (2) this command is similar to two successively executed commands:
zw ^ NameDictionaryElement (1) and zw ^ NameDictionaryElement (2)
Let's look at the result:
MONTOLOGY>zw ^NameDictionaryElement(1),^NameDictionaryElement(2)
^NameDictionaryElement(1,"partUri",0)="akp"
^NameDictionaryElement(1,"partUri",0,"UpdateTime")="62086,66625"
^NameDictionaryElement(1,"ru",0)="АКП"
^NameDictionaryElement(1,"ru",0,"UpdateTime")="62086,66625"
^NameDictionaryElement(2,"partUri",0)="meh"
^NameDictionaryElement(2,"partUri",0,"UpdateTime")="62086,66625"
^NameDictionaryElement(2,"ru",0)="МЕХ"
^NameDictionaryElement(2,"ru",0,"UpdateTime")="62086,66625"
MONTOLOGY>

As you can see, both elements have names in two languages: ru - Russian, partUri - is used in url. We also see that the names did not change after the addition - there is no history (there is only the current zero version).

Retrieve


Now we’ll write the simplest Dictionary program and add the retrieve function (method) to it — which will return the name of the directory element in the required language and version (code from a live project):
#; --------------------------------------------------------------------------------------------------
#; Имя программы
#; --------------------------------------------------------------------------------------------------
Dictionary
#; --------------------------------------------------------------------------------------------------
#; Получить элемент справочника.
#; --------------------------------------------------------------------------------------------------
retrieve(id,lang="ru",version=0)
	q $g(^NameDictionaryElement(id,lang,version),"")
#; --------------------------------------------------------------------------------------------------


q - abbreviated spelling of the quit command - (ala return)
$ g - abbreviated spelling of the $ get command - that is, a safe access to the variable, if there is no value for the given indexes - the default specified after the decimal point will be returned, in our case, the empty string ""

Now we bring Examples of calling our function (subroutine) The syntax of the call is as follows:
w $$ subroutine name ^ program name (parameters if any)
w is the abbreviated name of the write
$$ command means that the function that returns the value is written by the developer (if it is a system then the dollar sign is one).
Let the ^ symbol not bother youin a program call, because it is also used to access globals (global variables). The fact is that programs are stored in the same globals, such as those that I cited in the example (I will discuss this later). So, execute the following commands:
MONTOLOGY>w $$retrieve^Dictionary(1)
АКП
MONTOLOGY>w $$retrieve^Dictionary(2)
МЕХ
MONTOLOGY>w $$retrieve^Dictionary(1,"partUri")
akp
MONTOLOGY>w $$retrieve^Dictionary(2,"partUri")
meh
MONTOLOGY>

Of course, these examples did not go far from the school ones. In the future I plan to tell how index globals are arranged, how to create rule globals and programs working with these rules. Directories will have more complex structures. But the names of these globals will remain the same (new ones will simply be added) - they are really used in a living project, and the retrieve method too. All this in the following articles.

Thanks for attention.

I will be glad to questions and comments.

Only registered users can participate in the survey. Please come in.

You can change the name of any element of the directory in one place so that this change is applied throughout the system?

  • 78.2% Yes, I can. 18
  • 8.6% No, I can’t. 2
  • 13% I do not have a website (system) where I can check it. 3
  • 0% The question is not posed correctly. 0

Continue to write on this topic?

  • 91.3% Yes. 21
  • 8.6% None. 2

Also popular now: