An Empirical Study on the Design and Evolution of NoSQL Database Schemas

02/28/2020 ∙ by Stefanie Scherzinger, et al. ∙ 0

We study how software engineers design and evolve their domain model when building applications against NoSQL data stores. Specifically, we target Java projects that use object-NoSQL mappers to interface with schema-free NoSQL data stores. Given the source code of ten real-world database applications, we extract the implicit NoSQL database schema. We capture the sizes of the schemas, and investigate whether the schema is denormalized, as is recommended practice in data modeling for NoSQL data stores. Further, we analyze the entire project history, and with it, the evolution history of the NoSQL database schema. In doing so, we conduct the so far largest empirical study on NoSQL schema design and evolution.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 9

page 10

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

1 Introduction

Schema-flexible NoSQL data stores have become popular backends for building database applications. Systems like MongoDB allow for flexible changes to the domain model during application development. In particular, they have proven themselves in settings where applications are frequently deployed to their production environment, e.g., when web applications are built in an agile approach.

While the data stores do not enforce a global schema, the application code generally assumes that persisted entities adhere to a certain (if loose) domain model. Given that schema-flexibility is one of the major selling points of NoSQL data stores, this raises the question how the domain model, and thereby the implied NoSQL database schema, actually evolves. We empirically study the dynamics of NoSQL database schema evolution. Further, we investigate the question whether the NoSQL database schema is denormalized, as commonly recommended in literature, e.g. [15].

Unfortunately, real-world data dumps of NoSQL data stores are hard to come by. We therefore resort to analyzing the source code of applications hosted on GitHub. We focus on the relevant software stack shown in Figure (a)a, namely Java applications that use an object-NoSQL mapper to store data in either Google Cloud Datastore111https://cloud.google.com/datastore/, available since 2009. or MongoDB222https://www.mongodb.com/, available since 2019

, both popular and mature data stores. Among over 1.2K open source GitHub repositories with this stack, we have identified the ten projects with the largest NoSQL schemas (a notion introduced shortly).

Previous studies on schema evolution have primarily focused on schema-full, relational databases [5, 11, 13, 25, 20, 18]. About NoSQL schema evolution in real-world applications, little is known that is based on systematic, empirical studies (versus anecdotal evidence): Earlier studies have a different focus (such as the usage of certain mapper features [14]), or analyze a single project (c.f. [12]).

In this paper, we introduce our notion of the NoSQL database schema, which is implicit in object mapper class declarations, even though the underlying NoSQL data stores are schema-free. In this setting, this paper makes the following contributions:

  • We formulate three research questions, namely (RQ1) whether the NoSQL database schema is denormalized (as recommended in literature), (RQ2) which growth in complexity we can observe in NoSQL database schemas over the project development time, and (RQ3) how the NoSQL database schema evolves, thereby identifying the common changes.

  • We analyze the ten projects with the largest NoSQL database schemas among over 1.2K candidate projects, based on static code analysis and the commit history. We are able to confirm that denormalization is common in NoSQL database schemas. We are further able to show evidence of evolutionary changes to the NoSQL database schema in all analyzed projects.

  • We discuss our findings w.r.t. related studies on relational schema evolution and find that the churn rate of NoSQL schemas is comparatively high.

Structure. Next, we introduce preliminaries in Section 2. In Section 3, we describe our methodology, and state our research questions. In Section 4, we present the results of our study, which we then discuss in Section 5. We point out threats to the validity of our results in Section 6, and give an overview over related work in Section 7. We conclude with an outlook on future work.

2 Preliminaries

(a) The software stack.
(b) Code changes to class Player.
Figure 3: (a) The object-NoSQL mapper separates the domain model from the NoSQL data store (adapted from [6]). (b) Not all code changes are actually schema-relevant.

We next introduce the software stack studied, as well as our terminology.

Physical entities. We consider two popular NoSQL data stores: Google Cloud Datastore (called Datastore hereafter) is commercial and hosted on the Google Cloud Platform, MongoDB is open source. Both data stores are schema-free (however, MongoDB offers optional schema validation). Both manage document-like data, which we refer to as the (physical) entities. On an abstract level, an entity is a collection of key-value pairs, or properties. Entities may be nested and properties may be multi-valued. We sketch a Datastore entity representing a player and his or her missions in a role playing game in Figure (a)a, in (simplified) JSON notation, to abstract away from system-proprietary storage formats.

Domain models. In principle, each entity in a schema-free data store may have its very own, unique structure. However, in database applications, it is safe to assume that the software engineers have agreed on some domain model, as sketched in Figure (a)a. In our setting, the domain model is captured by Java class declarations, yet in the Figure, we use the more compact UML notation. (For now, we ignore the @-labeled annotations.) Class Player declares attributes for an identifier, a name, an amount of credits, and a list of missions. Each mission also has an identifier, a title, a level of difficulty, and tracks its completion.

Object-NoSQL Mappers. Object mappers are state-of-the-art in building database applications [6]. Like object-relational mappers, the object-NoSQL mappers Objectify333https://github.com/objectify/objectify and Morphia444https://github.com/MorphiaOrg/morphia map Java objects to entities. Objectify is tied to Datastore, and Morphia to MongoDB. With object-NoSQL mappers, developers merely specify their domain model as Java classes that are annotated with the keyword @Entity. Each entity-class has a unique key (annotated with @Id). The object mapper provides methods for saving and loading: In Figure (a)a, the class name and the identifying attribute are mapped to the designated properties _kind and _id. Objectify maps the player’s list of missions to an array of nested entities. Yet at application runtime, an entity-class declaration may not match the structure of all persisted entities, as discussed next.

Lazy data migration. The data store may also store legacy versions of entities. Figure (b)b shows a new version of entity-class Player, with changes due to new requirements in the software development project. Attribute coins has replaced credits. Merely changing the entity-class in the application code does not affect any existing entities. Instead, persisted entities are only migrated lazily, upon loading: The new version of entity-class Player in Figure (b)b is backwards-compatible with Figure (a)a. Once the legacy entity for Frodo has been loaded, the corresponding Java object will have an attribute coins, as annotation @AlsoLoad lazily renames attributes.

Thus, to obtain a summary of the structural variety of physical entities in the data store (based on code analysis alone, not having access to the data store contents itself), we need to consider the entire evolution history of entity-classes.

NoSQL database schema evolution. We base our notion of the NoSQL database schema (or shorter, NoSQL schema) on the domain model. This idea of treating entity-classes as schema declarations is re-current in literature, c.f. [4, 17]. Note that not all Java attributes are relevant for the NoSQL database schema: Attributes that are transient, e.g., carrying Objectify annotation @Ignore, are not schema-relevant: The value of hoursSinceLastLogin in Figure (b)b is not persisted (it may be derived from lastLogin). Also, class methods are not schema-relevant. Thus, code changes that only affect transient attributes or class methods are part of software evolution, but not of schema evolution. Therefore, they are not considered schema changes by us.

Denormalized entity-classes. The recommendation in working with Datastore and MongoDB is to intentionally denormalize the schema.555E.g. “6 Rules of Thumb for MongoDB Schema Design” at https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-2, June 2015. This can be done by either nesting entities, or by using multi-valued properties, such as the array of Missions in Figure 14. There are various motivations for denormalization, one being that traditionally, the query languages do not provide a join operator (such is still the case in Google Cloud Datastore, and this also used to be the case for MongoDB), so joined data is materialized in the data store. Another reason is that transactions between an arbitrary number of entities may not be supported666We point to the concepts such of entity groups and cross-group transactions in the classic Google Cloud Datastore [16], which is in the process of being deprecated.. Consequently, transactionally safe updates are often realized by updates to a single, aggregate entity.

In the following, we say an entity-class is denormalized if it does not declare flat, relational-style tuples in first normal form, i.e., with atomic attribute values only. So unless all schema-relevant attributes have Java primitive types (such as Integer, String, Boolean, …), we say the entity-class is denormalized. As we discuss in Section 3.3, this is a practical yet conservative approach.

As an example, the entity-class declarations for players, sketched in Figure 3, is denormalized, due to the multi-valued attribute listOfMissions.

3 Methodology

In the following, we describe our methodology, such as the context of our analysis, the research questions, and the analysis process. While our outline has strong analogies to Qiu et al. [13] and their analysis of relational schema evolution, our process is rather different: we cannot analyze schemas declared in a declarative data definition language, such as SQL. Rather, we need to parse raw Java code.

3.1 Context

We used BigQuery777Google BigQuery is a commercial cloud service. This data warehousing tool allows for querying the GitHub open data collection, mostly non-forked projects with an open source license: https://cloud.google.com/bigquery/. to identify relevant open source repositories on GitHub, as of September 4th, 2018. We consider a repository (which we synonymously refer to as a project) relevant if it contains Java import statements for Objectify or Morphia. We cloned over 1.2K candidate repositories and excluded any repositories that (1) have fewer than 20 commits (to exclude tinker projects), (2) are the Morphia or Objectify source code (or forks thereof), (3) or are flagged as forks from repositories already covered, with no schema-relevant code changes after the fork. We analyze the project history using git log888We state the exact command pattern for reproducability: git log --before=2018-09-04T00:00:00 --cherry-pick --date-order --pretty=format:"%H;%aI;%cI;%P".. This allows us to re-trace the development history of all entity classes. We parse and aggregate the log output using Python scripts.

Among all projects analyzed, we determined the maximum number of entity-classes throughout the project history, and settled on the top-5 projects for Objectify and Morphia respectively. Table 1 lists these projects with their life cycles up to the latest commit at the time of our analysis. We also state the total number of commits at the time. We state the minimum and maximum number of entity-classes throughout the project history, as well as the total number of lines of code between the first and last analyzed commit (measured with cloc999https://github.com/AlDanial/cloc and reported in thousands).

Project Life Cycle # Commits
# Entity-
classes
LoC (K)

Objectify

Cryptonomica/cryptonomica 04/16 09/18 185 0 29 0 526
FraunhoferCESE/madcap 12/14 03/18 853 0 82 0 17
google/nomulus 03/16 09/18 2,025 51 55 138 224
nareshPokhriyal86/testing 01/15 02/15 25 0 79 0 449
Nekorp/Tikal-Technology 04/15 11/15 59 0 43 0 49

Morphia

altiplanogao/tallyframework 06/15 06/16 167 0 24 0 5
bujilvxing/QinShihuang 10/16 12/16 154 0 36 0 21
catedrasaes-umu/NoSQLDataEngineering 11/16 09/18 711 0 28 0 280
GBPeters/PubInt 10/16 02/18 69 0 27 0 5
MKLab-ITI/simmo 07/14 02/17 142 0 51 0 5
Table 1: Characteristics of the studied database applications.

3.2 Research Questions

RQ1: Are NoSQL schemas denormalized?

We analyze the structure of entity-classes, whether they map to flat tuples in first normal form, or whether they represent denormalized data.

RQ2: What is the growth in complexity of the NoSQL schema?

We capture schema complexity based on metrics recognized in literature.

RQ3: How does the NoSQL schema evolve?

We automatically identify and classify evolutionary changes to the NoSQL schema.

3.3 Analysis Process

Locating entity-classes. We replay the commit histories and use the Java parser QDox101010https://github.com/paul-hammant/qdox to parse class declarations. We identify entity-classes by the object mapper annotation @Entity, which may also be inherited.111111In earlier versions of the mapper libraries, this annotation was only optional, so it cannot be relied upon. We therefore also search for the mandatory annotation @Id, and thus reliably detect polymorphic entity-classes. (c.f. Section 6).

Denormalization. To determine whether an entity-class is denormalized, we parse its Java declaration and strip away attributes that are not relevant to the NoSQL schema. We then analyze the types of the remaining attributes. Unless all have primitive types (such as Integer, String, or Boolean), we assume that the entity-class is denormalized.

In most cases, we correctly recognize denormalization: (1) if the entity class declaration contains container classes (e.g., a Java Collection), and therefore an attribute is multi-valued. (2) Equally, the entity-class may contain nested entity classes, giving it a hierarchical structure.

However, there are also cases where this approach is a conservative simplification, and we might falsely categorize an entity-class as denormalized: an attribute type may be declared in a third-party library, which is inaccessible to us (see also our discussion in Section 6). Also, an attribute type may be a custom type that the developers declared. To realize that a custom type is just a wrapper for a basic Java type, we would have to run more involved code analysis. Yet typically, polymorphic types are involved, and we are confronted with the inherent limitations of static code analysis.

Identifying schema changes. We identify commits with schema-relevant changes by comparing succeeding versions of the application source code: We register when (1) a new entity-class is added or an entity-class is removed, (2) a schema-relevant attribute is added or removed in an entity-class declaration, and (3) further, changes to schema-relevant attributes, such as to their types, default initializations, or even object mapper annotations. We only focus on changes which we can recognize programmatically. Recognizing renaming or splitting an entity-class, or renaming an attribute, are instances of the challenge of schema matching and mapping [2], and cannot be fully automated.

4 Results of the Study

(a) Objectify-based projects.
(b) Morphia-based projects.
Figure 6: Visualization of denormalized NoSQL database schemas.

4.1 RQ1: Are NoSQL schemas denormalized?

We analyze the entity-class declarations in their most current version w.r.t. denormalization. The results are visualized in Figure 6. For each analyzed project, we show a dot matrix chart. The number of dots represents the number of entity-classes. The brighter (orange) dots represent the entity-class declarations which we must assume to be denormalized, due to the limits of static code analysis. The darker (blue) dots represent the other entity-classes.

Notably, each project contains at least one denormalized entity-class, so all schemas are denormalized. With the exception of two Objectify-based projects, denormalized entity-classes dominate the NoSQL database schemas. There are even two Morphia-based projects where all entity-classes are denormalized.

Results. We find that each project analyzed has denormalized entity-classes in its NoSQL schema. This shows that developers make active use of denormalization. However, without qualitative studies based on developer surveys, we do not know whether (1) the developers consciously chose a database which allows for a denormalized database schema, as this better suits their conceptual model. However, it could also be that (2) they are actually forced denormalize their data model, due to the technological limitations of NoSQL data stores (briefly discussed in Section 2).

(a) Objectify-based projects.
(b) Morphia-based projects.
Figure 9: Evolution trend of entity classes. The horizontal axes show the project progress, in percentage of commits analyzed. The vertical axes show the complexity of the schema w.r.t. its maximum, for two alternative metrics. (Visualization modeled after [13].)

4.2 RQ2: What is the growth in complexity of the NoSQL schema?

In empirical studies on relational schema evolution, the number of tables is considered a simple approximation for schema complexity [7]. Accordingly, we track the number of entity-classes over time in Figure 9 (based on a visualization idea from [13]). For each project, one chart is shown. On the horizontal axis, we track the progress of the project, measured as the percentage of git commits analyzed. For the madcap project, this is based on 853 commits (c.f. Table 1). On the vertical axis, we track the size of the NoSQL database schema using two metrics. One is the number of entity classes (blue solid line). This metric is also normalized w.r.t. its maximum throughout the project history. So for madcap, the 100% peak corresponds to 82 entity classes, some of which were removed in the later phase of the project.

The second line denotes a “proxy metric” [7] for approximating the size of the NoSQL schema, where we count the lines of code of the entity-classes (including superclasses, excluding comments and empty lines), and thereby compute the Schema-LoC.121212We find this proxy-metric preferable over counting (schema-relevant) attributes, as is common in studies on relational schema evolution: (1) Entity-classes with more schema-relevant attributes have more lines of code accordingly. (2) In static code analysis, we cannot reliably count nested attributes: Abstract container classes and the use of polymorphism in general, make it impossible to know the number and nature of nested attributes at compile time. With Schema-LoC, we are able to abstract from this issue. There is shrinkage, yet overall, schema complexity increases.

Results. 1) As in the study by Qiu et al. on relational software evolution [13], we can confirm that while the projects differ in their life-spans and commit activity, in nearly all projects, the NoSQL schema grows over time. However, there may be phases of refactoring, leading to dips in the curves. 2) Apparently, Schema-LoC lends itself nicely as a proxy-metric, and we obtain high correlation coefficients when comparing to the number of entity classes. As Schema-LoC depends on the number of attributes in an entity class, we can retrace an effect reported in [13], namely that entity-classes and their attributes (corresponding to tables and columns) have largely analogous dynamics. 4) In general, the schema grows more than it shrinks. This is in line with studies on relational schema evolution. 5) One observation in [13] was that the schema stabilizes early: There, for 7 out of 10 projects, 60% of the maximum number of tables is reached in the first 20% of the commits. Interestingly, in our study, the number of entity-classes reaches the 60% in only 4 projects. 6) In [13], less than 2% of all commits contain valid schema changes (across all ten projects analyzed there). In our study, the share of commits with schema-relevant changes is between 2.8% and over 30%, with 4 projects reaching over 20%. Clearly, we observe higher churn rates.

Figure 10: Visualizing relative schema sizes and churn. Each rectangle represents an entity-class, its area proportional to its size in lines of code (specifically Schema-LoC). The hue represents the relative frequency of schema changes within the same project.
(a) By project.
Entity-class Schema-relevant attribute
 add remove add remove change
Objectify 56.3% 8.4% 24.7% 4.0% 6.5%
Morphia 34.5% 16.2% 21.6% 10.4% 17.2%
Overall 34.8% 15.1% 27.3% 7.4% 15.4 %
(b) Objectify-based vs. Morphia-based projects.
Project Type Initialization Annotations

Objectify

Cryptonomica/cryptonomica 2 0 3
FraunhoferCESE/madcap 9 0 6
google/nomulus 11 2 58
nareshPokhriyal86/testing 0 0 0
Nekorp/Tikal-Technology 0 0 3

Morphia

altiplanogao/tallyframework 7 3 54
bujilvxing/QinShihuang 32 33 15
catedrasaes-umu/NoSQLDataEngineering 43 0 13
GBPeters/PubInt 0 2 2
MKLab-ITI/simmo 7 5 18
(c) Drill-down into the remaining changes to schema-relevant attributes.
Figure 14: Distinguishing different kinds of schema changes: (a) and (b): Relative shares of schema changes (by project and by mapper library). (c) Zooming in on the remaining changes in schema-relevant attributes mentioned in (a), showing absolute values.

4.3 RQ3: How does the NoSQL schema evolve?

We first investigate how often entity-classes undergo schema changes when compared to others inside the same project, and how large they are in terms of our proxy metric Schema-LoC. Figure 10 visualizes the entity classes making up the ten NoSQL schemas as a tree map. This figure is best viewed in color. Each colored area represents one project. Inside, each rectangle represents one entity-class, the area proportional to its Schema-LoC. Darker hue indicates that an entity-class has undergone more schema changes than the other entity-classes in the same project. For instance, for nomulus, the darkest area represents 12 schema changes against the same entity-class. Thus, some entity-classes change quite more often than others. However, there are also projects where schema changes affect entity-classes quite uniformly.

In Figure 14, we capture the distribution of schema changes according to the kind of change. In Subfigure (a)a (after Qiu et al. in [13]), we break down the distribution of changes by project. Note that when a new entity-class is added, we do not count this as adding attributes at the same time. Notably, the distributions are project-specific. We now discuss two projects that stand out.

In the fourth Objectify-based project, adding an entity-class makes up for nearly all changes. Considering the project characteristics in Table 1

reveals that this project is an outlier in several regards: With only 25 commits, it has barely made the bar for being considered in our analysis (see Section 

3.1). At the same time, this project holds the second largest number of entity-classes in any project considered in this analysis. Since the life cycle considered is only two months, this project is in a very early stage of development at the time of this analysis. Thus, it seems plausible that at this early phase, the developers kick start their data model by declaring the entity classes in bulk.

In contrast, the second Morphia-based project stands out as the project with the least share of entity class additions. Since the git commit messages are in Chinese (which the authors of this paper do not master), we find it difficult to retrace the developers’ motivation. What is noticeable in Subfigure (b)b is that while the number of entity classes increases in less than 10 distinct steps, the proxy metric Schema-LoC changes in more fine-granular steps. Thus, the entity-classes undergo more frequent changes. This matches the distribution plotted, as then the share of entity-class creations is smaller by comparison. Subfigure (b)b summarizes Subfigure (a)a, and aggregates the changes by the mapper library. While we see project-specific fluctuations, when we group by mapper library, we also observe differences in the distribution. Overall, additions (whether of entity classes or of schema-relevant attributes) dominate.

In Table (c)c, we break down the schema-relevant attribute changes listed in Subfigures (a)a and (b)b: (a) For some projects, types change. (b) For others, the initialization changes. A drill-down reveals that (as may be expected) adding an initial value is the most frequent change, followed by changing the initialization value. (c) In other cases, mapper annotations that affect the schema are added or removed. The most frequent annotations added are @PersistField and @Reference. The first is from a third-party framework. Since it is schema-relevant, we report it. The second supports referential constraints. Sporadically, third-party annotations are added to declare additional constraints, such as @Min.

Results. 1) We can confirm the observations from related work on relational schema evolution that schema changes are generally not distributed uniformly [13, 23]. 2) As already observed for RQ2, the trend is that entity-classes are added more frequently than they are removed. We see a similar pattern for schema-relevant attributes, in line with studies on relational schema evolution. Overall, in 9 out of 10 projects, additions collectively account for more than 50% of the changes. In 5 projects, they even account for over 70% of the changes. 3) While additions are generally more frequent, there are also projects where removals of entity classes occur to a non-significant degree. Related work on relational schema evolution has shown that there are what the authors call survivor tables [24], whereas there are that are more short-lived. The observation that entity-class removals are very project specific has also been made in [13]. 4) Among all annotation changes, only 15 concern referential constraints (annotation @Reference). The authors of two relate studies on relational schema evolution, both [13] and [21], have observed that changes concerning referential integrity constraints are also rare in relational schema evolution. With NoSQL data stores, this is to be expected, as referential integrity is not supported to the same extent. 4) While Qiu et al. [13] found changes in attribute types to be the number one change for half of the projects analyzed (even outnumbering additions of either tables or columns), we do not see evidence of this effect here.

5 Discussion

We can reproduce the main results from related work on relational schema evolution: There is strong evidence of NoSQL schema evolution, and additions are dominant schema changes. However, we do not see the schema stabilizing in the early phases of all projects, which may partly be due to shorter project life spans: The ten projects studied in [13] are PHP applications backed by relational databases, and have longer life cycles (two with ten years), more commits (starting at nearly 5K), and more lines of code. This is to be expected with a much older and thus more widely adopted stack.

Still, we do suspect that NoSQL developers evolve their schema more continuously. One indicator supporting this hypothesis is that we see higher churn rates, so a larger share of the commits contains code changes that affect the schema. This calls for further study. Due to this churn, making sure that entity-class declarations are “backwards” compatible with legacy entities, persisted by earlier versions of the application code, may become an overwhelming task. There are first proposals for assisting tools, e.g., by type-checking versions of entity-class declarations [3]. Clearly, more research is needed on systematic tool support.

The fact that denormalization is common shows that solutions for managing relational schema evolution, managing flat tuples, will not transfer immediately. Rather, when devising frameworks, we may want to turn to related work on frameworks for handling schema evolution in XML (e.g. [9]) or object-oriented databases (e.g. [26]) for inspiration on what has shown to be feasible.

6 Threats to Validity

Construct validity. (1) With applications using older versions of Objectify and Morphia, we cannot rely on the @Entity-annotation to identify entity-classes, so we also consider the @Id annotation. To be confident that this does not lead to false positives, we performed manual checks. (With Objectify, we cross-checked which entity-classes were registered with ObjectifyService, a mandatory programming step.) (2) In static analysis, we encounter a limitation with attribute types from third-party libraries. Tracking down these libraries is out of scope (and not even possible in all cases). Thus, there are attributes that are not fully captured by Schema-LoC. Yet as this is a proxy-metric to start with, we consider this threat acceptable. Third-party libraries also affect the recognition of entity-classes as denormalized. Having sampled and inspected the entity-class declarations, we are confident that – given the limitations of static code analysis – the risk of false positives is acceptable. (3) We treat each single commit as contributing to a new version of the schema. There are software development teams that operate by continuous deployment, so tested code is immediately and autonomously deployed to the production environment. There, in theory, each commit containing a schema change comprises a new schema version. Yet rather often, a release to production comprises more than one commit. Unfortunately, we are not able to tell in static code analysis which commits where released when. There are development teams that tag release commits, but this is project-internal culture, and not consistently the practice across all ten studied projects. Therefore, we must go by the simplifying assumption that each commit declares a new NoSQL database schema.

External validity. We next discuss threats in generalizing our results to other software stacks. (1) It would be desirable to search additional code repositories, and extend to further NoSQL data stores, object mapper libraries, and programming languages. (2) Extending our analysis to projects that do not use object-mappers requires a different kind of static code analysis, and was implemented in a related study that involved a single MongoDB project [12]. At the same time, object mappers are state-of-the art in modern application development, and by now, Objectify and Morphia are actually part of official Datastore and MongoDB tutorials (even though they started as independent projects). Thus, we do analyze a highly relevant stack. (3) There is the fundamental question whether studies on open source projects generalize to commercial projects.

7 Related Work

Database schema evolution is a timeless research area, with various proposals how to systematically manage schema changes. Providing tool support, however, is not the scope of this paper. In the following discussion of related work, we therefore focus on empirical studies on schema evolution in open source projects.

It is only natural that the availability of public code repositories has enabled empirical studies on relational schema evolution [25, 5, 11, 13, 20, 18, 19, 22, 24]. Among their key findings, these studies show that the schema evolves. They confirm that adding tables or columns are frequent changes. In these settings, the schema is specified declaratively (usually in SQL). Accordingly, the term schema modification operations (SMOs) [5] does not transfer well to our stack. Rather than declarative DDL statements, we need to parse raw Java code: While the authors of [25] also parse application code, they do so to extract declarative statements embedded in code.

So far, there are only few empirical studies on schema evolution in NoSQL data stores. Our work builds on an earlier analysis [14] on the adoption of mapper annotations for lazy schema evolution, which is a different focus. The authors in [12] present an approach for identifying a schema evolution history in MongoDB-based Java applications. Different from us, the authors do not assume that an object-NoSQL mapper is used to access the data store. Rather, they analyze direct calls to the MongoDB API. The schema derived is similar to our notion of the NoSQL schema, since it captures the perspective of the application code. The authors evaluated their approach for a single open source project, whereas our study has a broader basis, considering ten projects. Moreover, their contribution is to derive a visualization of the schema evolution history.

Meanwhile, there is a growing body of work on extracting schema descriptions [1, 8, 4] from large collections of JSON data. While this a bottom-up approach, starting from the data, we proceed top-down, analyzing application code.

In capturing schema complexity based on Java class declarations, we could have resorted to software metrics [10]. However, it is not clear how metrics indicating an overly complex object-oriented design (e.g. classes with many attributes) transfer. The practice of building aggregate models in NoSQL schema design may actually be orthogonal.

We refer to [7] for a high-level discussion on schema variety versus code variety, as well as metrics for programmatic schema analysis.

8 Conclusion and Outlook

In this paper, we present the study on NoSQL schema evolution with the largest data basis so far, analyzing ten real-world, open source projects. We track the schema growth as well as the nature of changes to the NoSQL schema. We are able to reproduce most of the insights of related studies on relational schema evolution, but we have also identified subtle differences.

Since this is a first systematic study, many interesting questions remain unanswered. We remark on two. (1) Originally, we set out to compile detailed statistics on the structure of denormalized entity-classes, such as their nesting depth. However, we found that Java code written by experienced developers (e.g., as is the case with Google’s nomulus project) is highly polymorphic. This makes it impossible to compute reliable statistics based on the static analysis of entity-class declarations. However, more holistic analysis techniques, such as data flow analysis of the entire application code, might reveal further insights. (2)  We see evidence that the schema evolves, but we do not know the factors that influence NoSQL schema evolution. This calls for follow-up work, where we take the git commit messages into account, which often comment the reason for a schema change. What is also needed are qualitative studies, surveying developers who routinely deal with NoSQL schema evolution.

Acknowledgements

This project was funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation), grant number #385808805.

References

  • [1] M. A. Baazizi, D. Colazzo, G. Ghelli, and C. Sartiani (2019) Parametric schema inference for massive JSON datasets. VLDB J. 28 (4), pp. 497–521. Cited by: §7.
  • [2] Z. Bellahsene, A. Bonifati, and E. Rahm (2011) Schema Matching and Mapping. 1st edition, Springer Publishing Company, Incorporated. Cited by: §3.3.
  • [3] T. Cerqueus, E. Cunha de Almeida, and S. Scherzinger (2015) Safely Managing Data Variety in Big Data Software Development. In Proc. BIGDSE’15, Cited by: §5.
  • [4] A. H. Chillón, D. S. Ruiz, J. G. Molina, and S. F. Morales (2019) A Model-Driven Approach to Generate Schemas for Object-Document Mappers. IEEE Access 7, pp. 59126–59142. Cited by: §2, §7.
  • [5] C. A. Curino, L. Tanca, H. J. Moon, and C. Zaniolo (2008) Schema evolution in Wikipedia: Toward a Web Information System Benchmark. In Proc. ICEIS’08, Cited by: §1, §7.
  • [6] M. Fowler (2002) Patterns of enterprise application architecture. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA. External Links: ISBN 0321127420 Cited by: Figure 3, §2.
  • [7] S. Jain, D. Moritz, and B. Howe (2016) High variety cloud databases. In Proc. ICDE Workshops 2016, Cited by: §4.2, §4.2, §7.
  • [8] M. Klettke, U. Störl, and S. Scherzinger (2015)

    Schema Extraction and Structural Outlier Detection for JSON-based NoSQL Data Stores

    .
    In Proc. BTW’15, Cited by: §7.
  • [9] J. Klímek, J. Malý, M. Necaský, and I. Holubová (2015) eXolutio: Methodology for Design and Evolution of XML Schemas Using Conceptual Modeling. Informatica, Lith. Acad. Sci. 26 (3), pp. 453–472. Cited by: §5.
  • [10] M. Lanza and R. Marinescu (2010) Object-Oriented Metrics in Practice: Using Software Metrics to Characterize, Evaluate, and Improve the Design of Object-Oriented Systems. 1st edition, Springer Publishing Company, Incorporated. Cited by: §7.
  • [11] D. Lin and I. Neamtiu (2009) Collateral Evolution of Applications and Databases. In Proc. IWPSE-Evol’09, Cited by: §1, §7.
  • [12] L. Meurice and A. Cleve (2017) Supporting schema evolution in schema-less NoSQL data stores. In Proc. SANER’17, Cited by: §1, §6, §7.
  • [13] D. Qiu, B. Li, and Z. Su (2013) An Empirical Analysis of the Co-evolution of Schema and Code in Database Applications. In Proc. ESEC/FSE’13, Cited by: §1, §3, Figure 9, §4.2, §4.2, §4.3, §4.3, §5, §7.
  • [14] A. Ringlstetter, S. Scherzinger, and T. F. Bissyandé (2016) Data Model Evolution Using object-NoSQL Mappers: Folklore or State-of-the-art?. In Proc. BIGDSE’16, Cited by: §1, §7.
  • [15] P. J. Sadalage and M. Fowler (2012) NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence. 1st edition, Addison-Wesley Professional. Cited by: §1.
  • [16] D. Sanderson (2015) Programming Google App Engine with Java: Build & Run Scalable Java Applications on Google’s Infrastructure. 1st edition, O’Reilly Media, Inc.. External Links: ISBN 1491900202, 9781491900208 Cited by: footnote 6.
  • [17] S. Scherzinger, T. Cerqueus, and E. Cunha de Almeida (2015) ControVol: A framework for controlled schema evolution in NoSQL application development. In ICDE 2015, pp. 1464–1467. Cited by: §2.
  • [18] D. Sjøberg (1993) Quantifying schema evolution. Information & Software Technology 35 (1), pp. 35–44. Cited by: §1, §7.
  • [19] I. Skoulis, P. Vassiliadis, and A. V. Zarras (2014) Open-Source Databases: Within, Outside, or Beyond Lehman’s Laws of Software Evolution?. In Proc. CAiSE 2014, pp. 379–393. Cited by: §7.
  • [20] I. Skoulis, P. Vassiliadis, and A. V. Zarras (2015-10) Growing Up with Stability. Inf. Syst. 53 (C), pp. 363–385. External Links: ISSN 0306-4379 Cited by: §1, §7.
  • [21] P. Vassiliadis, M. Kolozoff, M. Zerva, and A. V. Zarras (2019) Schema evolution and foreign keys: a study on usage, heartbeat of change and relationship of foreign keys to table activity. Computing 101 (10), pp. 1431–1456. Cited by: §4.3.
  • [22] P. Vassiliadis, A. V. Zarras, and I. Skoulis (2015) How is Life for a Table in an Evolving Relational Schema? Birth, Death and Everything in Between. In Proc. ER 2015, pp. 453–466. Cited by: §7.
  • [23] P. Vassiliadis, A. V. Zarras, and I. Skoulis (2017) Gravitating to rigidity: Patterns of schema evolution - and its absence - in the lives of tables. Inf. Syst. 63, pp. 24–46. Cited by: §4.3.
  • [24] P. Vassiliadis and A. V. Zarras (2017) Survival in Schema Evolution: Putting the Lives of Survivor and Dead Tables in Counterpoint. In Proc. CAiSE 2017, pp. 333–347. Cited by: §4.3, §7.
  • [25] S. Wu and I. Neamtiu (2011) Schema Evolution Analysis for Embedded Databases. In Proc. ICDEW’11, Cited by: §1, §7.
  • [26] Xue Li (1999) A survey of schema evolution in object-oriented databases. In Proceedings Technology of Object-Oriented Languages and Systems, Vol. , pp. 362–371. Cited by: §5.