DataJoint has achieved Built-On status with DataBricks.

  • The Great Data Debate

    The Great Data Debate

    This article is Part 1 of our three-part series, AI Needs Data Discipline. In this opening installment, we explore the enduring debate between schema-on-write and schema-on-read, and how modern systems blend the two in data lakes, warehouses, and lakehouses. In Part 2, we’ll trace the mathematical foundations of structure and why they matter for AI.


    The Great Data Debate

    The Enduring Tension: Schema-on-Write vs. Schema-on-Read

    Long before AI became a ubiquitous topic, the data management world was already grappling with a fundamental question: when and how should we define the structure of our data? This debate centers on two primary philosophies: “schema-on-write” and “schema-on-read.”

    The traditional schema-on-write approach, familiar to anyone who has worked with relational databases, demands that we define the data’s blueprint—its fields, data types, and relationships—before any data is stored. Imagine meticulously designing an architectural plan before laying a single brick. This ensures consistency and predictability, as every piece of data has a designated place. However, this upfront design effort can make it challenging and costly to adapt if data formats need to change rapidly.

    Conversely, schema-on-read postpones defining structure until the data is actually queried. This approach gained significant traction with the NoSQL movement in the 2010s, driven by the need to handle the massive, diverse datasets (“Big Data”) generated by web applications. Schema-on-read allows for the quick ingestion of varied data types, offering great agility. Think of this as gathering all your building materials on-site and figuring out the assembly each time you need a structure. While flexible, this can sometimes lead to inconsistencies, as the interpretation of structure happens at the point of use.

    The choice often reflects a project’s ambition: unstructured approaches might let you build many simple cabins quickly, but only a planned, structured approach can yield a Burj Khalifa.

    The Hybrid Middle Ground: Data Lakes, Warehouses, and Lakehouses

    In today’s complex data landscape, many organizations don’t rigidly stick to one extreme. Instead, a hybrid approach is common. Raw data in its myriad formats (structured, semi-structured, unstructured) is often rapidly ingested into a data lake, a schema-on-read staging area. This “capture everything” strategy is great for speed and flexibility.

    However, when it comes to reliable analytics, reporting, and especially AI applications that demand high data quality, a transformation often occurs. Selected data from the lake is cleaned, validated, and loaded into a structured, schema-on-write system like a data warehouse.

    The more recent concept of the data lakehouse attempts to merge the best of both worlds. It aims to provide the flexible storage of a data lake with the robust data management, governance, and query performance features of a data warehouse, all within a single platform. Even in these advanced hybrid systems, a crucial principle often holds: while initial ingestion might be flexible (leaning towards schema-on-read), a subsequent step typically applies structure (schema-on-write) to ensure integrity for critical downstream applications, including AI.


    Why did the structured approach gain prominence in the first place? Part 2 of AI Needs Data Discipline, “The Power of Schemas,” describes the historical and theoretical foundations that make structured data so powerful and why it’s more than just a preference for order.

  • The New Scientific Enterprise

    The New Scientific Enterprise

    DataJoint and the Future of Knowledge Creation

    The world of scientific discovery is in flux, undergoing a transformation that redefines not only how research is conducted but also how its intellectual fruits are managed on a global scale. To understand the current juncture, it’s insightful to consider the historical trajectory of basic research across leading scientific nations.

    Before World War II, while universities globally, particularly in Europe, possessed strong traditions of fundamental inquiry, a significant portion of pioneering fundamental science also emerged from industrial laboratories in technologically advancing countries. In the United States, for instance, Bell Labs, an industrial research powerhouse, was the birthplace of the transistor in 1947—a discovery that, while occurring just post-war, was the fruit of pre-war and wartime research trajectories typical of an era where industry played a leading role in certain types of foundational science. Similarly, DuPont’s development of nylon in the 1930s, a groundbreaking synthetic material, stemmed from its corporate commitment to long-term chemical research. These examples illustrate an era where industrial investment was critical for certain capital-intensive, foundational breakthroughs, often in fields aligned with their commercial interests, yet profoundly expanding scientific frontiers.

    The landscape experienced a seismic shift following World War II, with different nations adapting their science policies. In the United States, this was famously catalyzed by influential reports like Vannevar Bush’s 1945 “Science, the Endless Frontier.” This advocated for massive, sustained federal investment in basic research, primarily through universities, as an engine for national progress. The subsequent establishment of agencies like the National Science Foundation (NSF) and the expansion of the National Institutes of Health (NIH) exemplified this strategy. This model, emphasizing publicly funded, university-based research, led to an explosion of academic discoveries, such as the elucidation of the DNA double helix structure in 1953 by Watson and Crick (supported by a mix of academic, philanthropic, and Medical Research Council funding in the UK), or the development of the laser and maser by Charles Townes and others (with university research often backed by government contracts). Other leading nations also significantly increased state funding for science, developing their own models that shaped the global scientific ecosystem and intensified both international collaboration and competition.

    As a result, universities and dedicated public research institutions worldwide became principal theaters for early-stage investigation. While leading corporations globally didn’t entirely abandon basic research—many maintained formidable research divisions pursuing strategic long-term goals—their relative proportion of national basic research efforts often changed. The focus of major public investment shifted towards academia for broad, non-directed inquiry.

    Today, academic and public research institutions remain the cornerstones of basic research. However, this model is profoundly tested. Public funding, while substantial, often struggles to keep pace with the escalating costs, complexity, and sheer scale required for cutting-edge science. A stark illustration of this trend is the development of modern large AI models. The foundational algorithmic breakthroughs and initial advancements in deep learning often emerged from academic settings, driven by researchers like Geoffrey Hinton, Yann LeCun, and Yoshua Bengio. However, the journey to the current state of powerful large language and generative AI models required computational resources, engineering teams, and datasets at a scale far beyond typical academic grant capabilities. It took trillion-dollar valuations driven by venture backing and massive corporate investment to achieve this, demonstrating that some areas of what is effectively basic research now demand financial and infrastructural scale previously unimagined for academic settings.

    This challenge is not unique to AI. For instance, discussions at pivotal meetings, such as the November 2024 NIH NeuroAI Workshop, which I had the privilege to join, have highlighted how advancing neuroscience to understand the brain’s immense complexity requires scalability in data acquisition, processing, and model-building not unlike that seen in leading AI companies. Participants noted that the traditional federal grant system is often poorly adapted to support the massive, collaborative, and computationally intensive joint studies of neuroscience and AI needed for transformative breakthroughs.

    This evolving global context necessitates a “new knowledge capitalism.” Basic science will likely continue to germinate primarily within academic labs, but their modes of integration with industry and, critically, their knowledge management approaches, must evolve. This new model involves recognizing and strategically managing all outputs of research—not just publications, but the intricate scientific workflows and the vast, curated acquired data—as valuable research assets.

    This upcoming transformation demands deliberate focus on knowledge ownership, licensing, and comprehensive data governance. As research becomes more collaborative and its outputs more complex and valuable, clarity on these issues is paramount. Academic institutions, departments, individual labs, and the researchers themselves will require and expect clear definitions of their respective ownership shares and usage rights for both intellectual property (methods, software, inventions) and the data assets generated. Robust data governance frameworks covering both the data itself (its quality, security, accessibility, and provenance) and the methods used to produce and analyze it will become central to the scientific enterprise.

    Research Communications in the New Knowledge Capitalism

    The imperatives of this new scientific enterprise also reshape our approach to research communication. It’s crucial to distinguish that the ideal methods for conducting science often differ significantly from those for effectively communicating science. The process of discovery is frequently complex, iterative, involving vast amounts of data, numerous analytical paths explored, and many supporting details. In contrast, research communication—be it in publications, presentations, or public discourse—thrives on simplicity, a clear focus on the main findings, and meticulously presented controls that substantiate these claims. Extraneous detail, while vital during the research process, can detract from the core message in its communication.

    The primary purpose of research communication is didactic; it aims to inform, educate, and allow the broader scientific community and society to understand and build upon new knowledge. Paramount to this is scientific integrity. Findings must be presented transparently and honestly, allowing for scrutiny and verification.

    This is where a platform like DataJoint plays a dual role. While it manages the full complexity of research conducted by teams—the intricate pipelines, diverse datasets, and varied computational explorations—it also provides the tools to support clear and responsible communication. DataJoint allows researchers to precisely extract specific cross-sections of data, analyses, and workflow components that directly underpin the scientific findings being communicated. This enables the creation of focused narratives supported by verifiable evidence.

    However, this capability must be wielded with profound scientific caution. The ability to select specific data or analytical approaches for presentation carries an inherent risk of bias, such as p-hacking (selectively reporting statistically significant results while ignoring non-significant ones) or cherry-picking data or methods that inappropriately inflate findings. In the new knowledge capitalism, where the perceived value of research assets is critical, maintaining the highest standards of integrity in communication is more important than ever.

    DataJoint can contribute to mitigating these risks, not by policing thought, but by enabling more transparent and accountable practices:

    • Traceability: Communicated findings can be directly traced back to their origins within the managed DataJoint pipeline, including specific data versions and computational steps.
    • Contextual Record: The full pipeline, potentially encompassing a broader range of analyses than what is presented in a concise communication, can serve as a comprehensive record. While not always fully public due to IP considerations, this underlying structure can support deeper dives by collaborators, reviewers (under appropriate agreements), or for internal validation.
    • Support for Rigor: By structuring the research process, DataJoint encourages systematic exploration and documentation, which, when combined with ethical research practices and pre-registration of analysis plans where appropriate, can help ensure that communicated results are robust and represent the science faithfully.

    Ultimately, while tools like DataJoint provide powerful capabilities for both conducting and communicating science, the responsibility for ethical conduct and transparent reporting rests with the researchers and the scientific community. In this new era, where scientific assets have explicit value, ensuring that communications are both compelling and rigorously honest is fundamental to building trust and fostering genuine progress.

    DataJoint: Enabling the Transformation

    DataJoint is at the forefront of this evolution, providing the framework for this new global scientific enterprise. We understand that for research entities to thrive, they need tools that facilitate both robust international collaboration and stringent protection and management of their unique assets:

    • Develop, Extend, and Preserve Research Workflows and Data Assets with Secure IP Retention: DataJoint provides a robust framework for creating, managing, and evolving complex data pipelines, treating both the workflow logic and the acquired data as first-class, interlinked assets. This systematic approach inherently documents the research process. DataJoint’s architecture enables granular control, allowing labs to define what is shared and with whom—whether collaborators are domestic or international—ensuring core intellectual property and sensitive data remain secure and properly attributed.
    • Achieve Seamless Compatibility with Global Partners (Data Ops, Research Ops, SciOps): DataJoint’s standardized data models and reproducible analyses align with rigorous operational demands worldwide, facilitating smoother international collaborations.
    • Champion Reproducible Science While Strategically Managing Know-How and Data Assets: DataJoint enables transparency for validation while empowering institutions and researchers to protect core methods and valuable datasets, balancing openness with the strategic management of assets in a competitive global environment.
    • Manage Knowledge Assets and Uphold FAIR Principles with Comprehensive Governance: DataJoint supports FAIR principles for both workflows and data. Crucially, it provides the infrastructure for implementing detailed data governance and defining knowledge ownership structures. Its relational database foundation and workflow management capabilities allow for precise tracking of contributions, data provenance, and processing steps, which is essential for delineating ownership and licensing rights among institutions, departments, labs, and individual researchers. This facilitates the clear articulation and enforcement of policies regarding data and IP sharing, usage, and commercialization.

    Empowering the Future: International Collaboration, Governance, Security, and Global Competitiveness

    The current scientific era is defined by unprecedented opportunities for international collaboration to tackle grand challenges. DataJoint provides a common operational language and robust data management infrastructure that allows geographically dispersed teams to work together seamlessly, share insights responsibly, and accelerate discovery.

    However, this occurs within a landscape of intense global competition. Nations and institutions vie for scientific leadership. DataJoint supports this by enabling rigorous data governance and IP management that helps protect a research entity’s competitive edge while still allowing for controlled collaboration. Its capabilities are crucial for implementing clear knowledge ownership and licensing frameworks, ensuring that contributions are properly recognized and benefits fairly distributed according to predefined agreements between universities, labs, and researchers.

    DataJoint is engineered to provide fine-grained access controls, auditable data and computation trails, and a secure environment. This allows entities to collaborate confidently, sharing necessary components of data and workflows while protecting proprietary elements critical to their strategic interests.

    The future of science is global, collaborative, and competitive, with an increasing emphasis on the strategic management of knowledge and data assets, and a renewed focus on the integrity of its communication. DataJoint is committed to empowering researchers and institutions worldwide to navigate this new landscape successfully, providing the tools to conduct world-class science, strategically manage their intellectual assets with clear governance and ownership structures, and forge a more impactful, secure, and sustainable scientific future for all.

  • You Only Need Five Query Operators

    You Only Need Five Query Operators

    Clarity in Complexity: Why DataJoint’s Five Query Operators Are All You Need

    Navigating complex data demands tools that offer both power and clarity. DataJoint is designed for building and managing scientific data pipelines. The upcoming release of DataJoint Specs 2.0 marks the first time DataJoint will be developed against a formal, open specification document, embodying the philosophy of an open standard and capturing its core theoretical concepts to ensure consistent implementations across different platforms.

    While many are familiar with SQL, the lingua franca of relational databases, DataJoint’s query language, as defined in these new specs, employs a remarkably concise set of just five core operators. This naturally begs the question: in a world accustomed to SQL’s extensive vocabulary, can just five operators truly be enough? This article argues an emphatic “yes” – not despite their small number, but precisely because of their rigorous design and unwavering commitment to fundamental relational principles.


    The Theoretical Bedrock, ERM’s Vision, and SQL’s Journey

    To appreciate DataJoint’s approach, it helps to understand the foundations. Relational database theory, pioneered by Edgar F. Codd in the late 1960s/early 1970s, is built on rigorous mathematics. Codd introduced relational algebra, a procedural language where operators like selection, projection, and join manipulate tables (relations) to produce new tables. He also defined relational calculus, a declarative language allowing users to specify what data they want. Codd proved these two formalisms were equivalent in power, establishing the concept of relational completeness.

    In 1976, a pivotal moment in conceptual database modeling arrived with Peter Chen’s introduction of the Entity-Relationship Model (ERM). Chen proposed a way to look at the world, and thus model data, in terms of “entities” (distinguishable “things” like a student or a course) and “relationships” between them (like a student “enrolling” in a course). The ERM provided a powerful visual language—ER diagrams—that became incredibly influential for database schema design and for communication between database designers, domain experts, and stakeholders. It offered an intuitive framework for translating real-world scenarios into structured data models, naturally leading to well-normalized schemas.

    However, a significant disconnect emerged. While ERM became a standard for conceptualizing and designing databases, its elegant, entity-centric syntax and explicit relationship constructs were never directly mirrored in SQL’s Data Definition Language (DDL for creating tables) or its Data Query Language (DQL for retrieving data). SQL’s CREATE TABLE statements, while defining columns and foreign keys (which implement ERM relationships), don’t speak the direct language of “entity sets” and “relationship sets” in the way ERM diagrams do. Similarly, SQL’s JOIN syntax, while powerful, doesn’t inherently guide users to join tables based on the semantically defined relationships from an ERM perspective. This left a gap between the clarity of the conceptual design and the often more intricate, attribute-level syntax of SQL implementation and querying.

    SQL itself emerged as a practical implementation drawing from both relational algebra and calculus. Its SELECT...FROM...WHERE structure has a declarative feel whereas JOIN is a relational algebra operator. A fascinating part of SQL’s early vision was its aspiration to be a natural language interface for databases, aiming for queries that read like English prose. While admirable, this came at the cost of the explicit operator sequencing and rigorous composability found in more formal algebraic systems.

    SQL’s widespread adoption, fueled by successful standardization efforts, has been immensely beneficial. However, through its evolution, SQL accumulated “conceptual baggage”—layers of complexity and ambiguity that can obscure the underlying simplicity of relational operations.


    The Cornerstone: Well-Defined Query Results

    A central tenet of the DataJoint philosophy, crystallized in the new Specs 2.0, is that all data, whether stored in base tables or derived through queries, must represent well-formed entity sets (or relations). What does this mean in practice? It means that every table, including any intermediate or final result of a query, must:

    • Clearly represent a single, identifiable type of entity (e.g., “Students,” “Experiments,” “MeasurementEvents”).
    • Have a well-defined primary key – a set of attributes whose values uniquely identify each entity (row) within that set.
    • Ensure that all its attributes properly describe the entity identified by that primary key.

    This commitment is upheld through what the DataJoint Specs refer to as algebraic closure. Each of DataJoint’s query operators is designed such that if you give it well-formed relations as input, it will always produce another well-formed relation as output, complete with its own clear primary key and entity type.

    This brings us to a critical question to keep in mind when working with SQL: Can you always tell, just by looking at the SQL statement, what real-world entity each row in the result is meant to represent, and what makes each row unique? Often, the answer becomes murky.


    DataJoint’s “Fab Five”: A Modern Interface to Relational Power

    With deep reverence for Codd’s foundational genius, it’s fair to ask if the original set of algebraic operators, defined over half a century ago, still constitutes the optimal user-facing interface for today’s data challenges. DataJoint, guided by its new Specs 2.0, proposes a refined, modern set of five operators designed for clarity and power:

    1. Restriction (&, -): This is your precision filter. It selects a subset of rows from a table based on specified conditions without altering the table’s structure or primary key. The resulting table contains the same type of entities and the same primary key.
    2. Projection (.proj()): This operator reshapes your view of a table by selecting specific attributes, renaming them, or computing new attributes from existing ones. Crucially, the primary key of the original table is preserved, ensuring the identity of the entities remains intact.
    3. Join (*): This operator combines information from two tables. But it’s not just any combination; it’s a “semantic join” (more on this later) that ensures the resulting table represents a meaningful fusion of entities, with a clearly defined primary key derived from its operands.
    4. Aggregation (.aggr()): This operator can be seen as an advanced form of projection. For a table A, A.aggr(B, ...) can perform the same functions as A.proj(...)by selecting, renaming, and calculating attributes. Additionally, it can also calculate new attributes for each entity in A by summarizing related data from table B. The beauty is that the resulting table still has A‘s primary key and represents entities of type A, now augmented with new information.  Despite their similarity, we consider .proj and .aggr as distinct operators.
    5. Union (+): This operator combines rows from two tables, A and B. For this to be valid, A and B must represent the same type of entity and share the same primary key structure; the result inherits this structure.

    These five operators, through their strict adherence to producing well-defined results, form the backbone of DataJoint’s expressive power.


    Untangling SQL: Where Simplicity Meets a Wall of Operators (Illustrated)

    Let’s look at how DataJoint’s approach contrasts with SQL in practice.

    SQL’s Operator Count – A Fuzzy Number

    How many “operators” does SQL effectively have? It’s notoriously hard to quantify because many distinct logical operations are bundled into the complex SELECT statement. A single SELECT can perform filtering (like DataJoint’s restriction), column selection and computation (projection), table combination (join), grouping, and ordering, all intertwined.

    Furthermore, seemingly simple modifiers in SQL can act like entirely new, transformative operators. Adding DISTINCT to a SELECT query doesn’t just remove duplicate rows; it fundamentally changes the resulting relation, implying a new primary key based on all the selected columns. Similarly, aggregate functions like COUNT() or AVG() within a SELECT statement, with and without a GROUP BY clause, transform the output into a new type of entity (e.g., “summary per department” instead of “employees”), with the grouping columns forming the new primary key. If we were to “unroll” every distinct transformation SQL can perform, the operator count would be vastly larger and far more entangled than DataJoint’s explicit five.

    The SELECT Statement’s Hidden Logic

    The order in which SQL clauses are written (SELECT, FROM, WHERE, etc.) doesn’t reflect their logical execution order. This “hidden logic” often confuses users, particularly regarding the scope of aliases defined in the SELECT list. DataJoint’s explicit, sequential application of operators avoids this ambiguity entirely.

    The Labyrinth of SQL Joins vs. DataJoint’s Semantic Precision

    SQL offers various join implementations like INNER JOIN, LEFT/RIGHT/FULL OUTER JOIN, and CROSS JOIN with various modifiers such as NATURAL, USING, and ON <condition>.  Classical relational algebra also defined foundational concepts such as equijoin (joining based on equality, a specific type of a more general “theta join” which allows any comparison – though these terms are more academic than direct SQL syntax) and natural join, which have influenced SQL’s join logic. However, SQL’s NATURAL JOIN (matching on identically named columns) can be treacherous, as it may join attributes that share a name but have completely different meanings.

    The ERM guided that meaningful joins should occur on foreign keys between related tables. DataJoint institutionalizes this with Semantic Matching for its one and only join (*) operator. For attributes to be matched, they must not only share the same name but also trace their lineage through an uninterrupted chain of foreign keys to the same original attribute definition. If identically named attributes don’t meet this criterion, it’s a “collision,” and DataJoint raises an error, compelling the user to explicitly rename attributes using projection before the join. This rigor, tied to the foreign key relationships typically visualized in a schema diagram, means the validity of a DataJoint join is often apparent from the schema structure itself.

    Semijoin and Antijoin: The Illegitimate “Joins”

    Speaking of joins, relational algebra textbooks often discuss semijoin and antijoin.

    • A semijoin (A⋉B) returns rows from table A for which there is at least one matching row in table B (based on common attributes), but it only includes columns from table A.
    • An antijoin (A▹B) returns rows from table A for which there are no matching rows in table B, again only including columns from table A.

    While these are powerful, the “join” in their names is quite a misnomer. True joins combine attributes from both participating tables to form a new, wider entity and create new entities by pairing rows from the joined tables. Semijoins and antijoins, however, don’t do this. They fundamentally act as filters on table A based on the existence (or non-existence) of related records in table B. The structure of table A (its attributes and primary key) remains unchanged; you merely get a subset of its rows. This is precisely the definition of a restriction operation.

    In SQL, these operators are implemented in a wide variety of ways, typically using a subquery with EXISTS, NOT EXISTS, IN, and NOT IN operators, or as an inner join followed by a GROUP BY or by using a DISTINCT modifier.

    The DataJoint Specs 2.0 acknowledge the true restriction-like nature of these operators directly: when performing a restriction by a subquery (which is conceptually how one table filters another), “The restriction acts as a semijoin (for &) or an antijoin (for -)” . The earlier DataJoint manuscript (Yatsenko et al., 2018) also explicitly deprecated the terms “semijoin” and “antijoin” as misleading and confusing. DataJoint thus correctly categorizes these operations under its versatile Restriction operator, avoiding the potential confusion of SQL needing EXISTS, NOT EXISTS, IN, or NOT IN subqueries to achieve similar effects, which can feel less direct than a simple restriction.

    SQL’s OUTER JOINs: A Mix of Meanings

    SQL’s OUTER JOIN variants (like LEFT JOIN) often create results that are a jumble of entity types. Some rows might represent a complete pairing, while others represent only one entity, padded with NULLs. After such an operation, can you confidently tell what real-world entity each row in the result is meant to represent?

    DataJoint’s Specs 2.0 clearly state its approach: it effectively has no direct “outer join” operator because such an operation typically violates the principle of yielding a single, well-defined entity set with a consistent primary key. Instead, DataJoint’s aggr operator cleanly achieves the common goal of augmenting one entity set with summaries from another, preserving the primary entity’s type and identity.

    Redundancy in Restriction in SQL

    SQL uses multiple clauses for what amounts to filtering: WHERE, ON (in joins), HAVING (for groups), and LIMIT / OFFSET (for result sets). DataJoint streamlines this with its single, powerful Restriction operator (& and its complement -).


    Illustrative Examples: DataJoint vs. SQL

    Let’s make these differences more concrete. (Imagine a simplified university database with Student, Course, Section, Enroll, StudentMajor, and Grade tables.)

    1. Finding Students Enrolled in Any Class

    • DataJoint:
    Student & Enroll 
    • Result: A well-defined set of Student entities.
    • SQL:
    SELECT *
    FROM Student
    WHERE student_id in (SELECT student_id FROM Enroll);

    Result: Rows from the Student table, but the logic is more verbose.

    2. Counting Enrolled Students per Section

    • DataJoint:
    Section.aggr(Enroll, n_students='COUNT(*)')

    Result: Section entities, augmented with n_students.

    • SQL:
    SELECT sec.*, COUNT(e.student_id) AS n_students
    FROM Section AS sec
    LEFT JOIN Enroll AS e USING (course_id, section_id)
    GROUP BY course_id, section_id

    Result: Requires explicit join and grouping by all parts of Section‘s primary key.


    The DataJoint Advantage: Why These Five Excel

    DataJoint’s design philosophy demonstrates that true power doesn’t come from a multitude of overlapping commands, but from a concise set of orthogonal, well-defined operators that compose reliably.

    • Consistently Well-Defined Results (Algebraic Closure): Every operation yields a predictable, valid table with a defined primary key and entity type.
    • Semantic Precision: Binary operations like join are based on meaningful relational links, not just coincidental name matches.
    • Composability: Simple, reliable steps can be combined to build sophisticated queries.
    • Interpretability: The nature of the data remains clear at every stage of the query.
    • Entity-Oriented Focus: The operators encourage thinking in terms of whole entities and their relationships, aligning well with conceptual modeling principles championed by the ERM as opposed to the attribute-oriented focus of SQL.

    Conclusion: A Clearer Lens for Data Discovery

    SQL’s position as a foundational data language is secure, and its contributions are undeniable. However, for the complex, high-stakes data work found in scientific research and other demanding domains, a query interface that prioritizes conceptual clarity, predictability, and semantic integrity can be transformative.

    DataJoint, as guided by its new Specs 2.0, isn’t about minimalism for its own sake. It’s about providing a complete and conceptually sound set of query operators that empower users. By ensuring every operation results in a well-defined entity set and by enforcing semantic integrity in operations like joins, DataJoint aims to strip away ambiguity and allow researchers to interact with their data with greater confidence and insight. It’s a compelling case that sometimes, to see further, we need not more tools, but clearer lenses.

  • A Better Data Engine for Brain Science

    A Better Data Engine for Brain Science

    This computational platform is helping labs manage complex data pipelines and laying the foundation for AI-driven discoveries in neuroscience and beyond.


    Originally published in Nature (April 2025), this piece explores how DataJoint's computational platform is transforming neuroscience research for labs around the world. The current version, slightly expanded from the original, has been updated to reflect the recent Executive Order on Gold Standard Science, emphasizing reproducibility and transparency as national scientific priorities for the United States.

    Click to download a PDF of the original Nature article.


    Scientific research is often celebrated for its creative chaos — improvisation in the lab, trial-and-error in the field, the occasional serendipitous breakthrough. But as experiments become increasingly data-heavy, with reams of complex inputs and computational analyses, researchers are struggling to scale their operations while maintaining rigor and reproducibility.

    A new proposal, outlined in a recent preprint, aims to change that. By adapting best practices from software engineering to scientific research, a coalition of academic and industry partners hopes to streamline data collection, standardize analyses and accelerate discovery — with structured workflows seen as key to this effort. This effort aligns directly with the recent Executive Order on Gold Standard Science, which prioritizes reproducibility and transparency as foundational standards for federally-funded research.

    “The goal, fundamentally, is to produce the same productivity increase in science that we have seen in other disciplines,” says Dimitri Yatsenko, a lead architect of the new ‘SciOps’ framework.

    The concept takes inspiration from DevOps, which transformed software development in the 2000s by empowering teams with automated workflows, continuous testing, and seamless code integration. DevOps made it possible to create entirely new industries like cloud computing, e-commerce and streaming.

    Academic research needs a similar shift, says Yatsenko, and he has created a data operations platform for scientific laboratories to help make that happen. Known as DataJoint, the platform replaces fragmented data handling processes with an end-to-end computational workflow for data entry, acquisition, processing, analysis and visualization — all unified in a coherent pipeline that unlocks collaboration and integration with artificial intelligence (AI) capabilities.

    “A key challenge in data science is to combine computations with data management,” notes Yatsenko, founder and chief scientist of a company that shares the platform’s name. “DataJoint handles that as a single problem,” he says.

    Available as an open-source general framework, DataJoint is adaptable for any research discipline, from genomics to climate science. But to date, it has had the most impact in systems-level neuroscience, where data integrity and reproducibility are persistent challenges.

    Supporting MICrONS

    In 2016, the platform was selected as the data backbone for the neurophysiology component of the Machine Intelligence from Cortical Networks (MICrONS) project — a five-year, US$100- million initiative funded by the US Intelligence Advanced Research Projects Activity to map the detailed structure and activity of neural circuits in the mouse brain. DataJoint’s adoption helped establish its value in managing large-scale, multi-modal neuroscience data.

    With an eye toward informing next-generation machine learning models that ‘think’ like brains, the MICrONS team collected petabytes of data from electron microscopy (to map synaptic connections), calcium imaging (to track neural activity) and behavioral studies (to understand functional responses) in mice.


    DataJoint enabled the MICrONS team to train a new foundation model by capturing the brain in unprecedented detail. With NIH support, DataJoint has translated the system that powered MICrONS into a scalable platform — bringing the same robust data infrastructure to any lab working at the frontiers of neuroscience and AI.

    In vivo recorded data on inputs (visual stimulus, eye position, locomotion, and pupil size) and outputs (neural activity) trains an artificial neural network model to generate in silico responses. See Foundation model of neural activity predicts response to new stimulus types, Figure 1.

    Another DataJoint pipeline integrated the functional data with structural data from systems like CAVE — which, as reported in Nature, enabled scientists to start teasing apart the computational principles that underlie the function and connectivity of the mammalian brain.

    Finishing the job won’t be easy. But with much of the data available via DataJoint and the MICrONS Explorer, researchers can continue to explore new questions about neural computation and circuit dynamics. “I think the MICrONS data will be studied for the next decade or more,” Yatsenko says.

    ‘Just essential’

    Beyond MICrONS, over 100 neuroscience labs worldwide use the platform for data pipelines in studies on neurodegenerative disease, neurotransmitter signaling, visual processing, and stroke recovery. Several large, multi- institutional projects, focused on understanding cognition, olfaction, and behavior, also rely on DataJoint.

    Before adopting the platform, researchers often relied on convoluted file naming conventions, custom-written code and incompatible formats that complicated data handling. DataJoint eliminates that chaos by centralizing data management, automating analyses and ensuring consistency — and traceability — across experiments. These capabilities are particularly critical now, as the recent Executive Order elevates reproducibility and transparency from best practices to federally mandated priorities.

    “I’m so enthusiastic about it,” says Jacob Reimer, assistant professor of neuroscience at Baylor College of Medicine (BCM) in Houston, who was an early adopter of the platform there. “Everything we do is now immediately accessible and easily located,” he adds. “There’s no other place the data can be.”

    Reimer had a front-row seat to DataJoint’s early development. As a postdoc working in the same BCM lab, Reimer watched Yatsenko, then a graduate student, spend his free time, between imaging experiments of calcium signals in the mouse brain, working on building a better way to manage the growing data deluge.

    At first, most colleagues ignored or outright dismissed Yatsenko’s effort. “Nobody was convinced it was worthwhile,” says Reimer. But then Yatsenko unveiled an early prototype, and, quickly, recalls Reimer, “it became, like, just essential.”

    The entire lab soon implemented the platform. So too did collaborators from California and Germany. And by 2016, as interest spread, Yatsenko, together with Reimer and two other members of the same BCM lab group, decided to the DataJoint company — of which Reimer remains a shareholder — to scale the platform for broader use.

    Expanding reach

    More labs continue to adopt DataJoint to manage and refine their own data operations, with the company’s services and capabilities growing in response to demand.

    “Labs must invest in their data operations to stay competitive, given the growing importance of AI and advanced data science techniques,” says Marshall Hussain Shuler, a neuroscientist at Johns Hopkins University School of Medicine in Baltimore, Maryland. His lab gathers mounds of microscopy and video imaging to study the electrophysiology and behavior of neural circuits in mice, aiming to understand how experiences shape sensory processing and decision-making. “Making a platform that does all that in one place is a tall order,” he says. DataJoint helps keep it all organized and interpretable, creating what he calls a “lab memory.”

    “We have already saved months and ran experiments that we never could before,” Hussain Shuler says. “DataJoint allows us to create a formal structure for our work that can be understood, extended, and reused.”

    That structure is helping the team behind Project Aeon, led by the Sainsbury Wellcome Centre at University College London, to better understand the neural basis of natural mouse behaviors, such as foraging, escaping, nesting, and social interactions over naturalistic timescales. The project involves continuous monitoring of mice in large habitats, via dozens of cameras and sensors, for weeks to months, producing high-dimensional quantifications of their behavioural repertoire including pose, position, and identity. “Such in-depth description of mouse behavior, combined with prolonged ephys recordings from implanted arrays, generates very large and complex datasets that are hard to handle,” says Dario Campagner, Project Lead Scientist. “DataJoint architecture enables fast and intuitive data querying and provides an easy way to standardize the data format for sharing with researchers all over the world.”

    Scrutinizing all that data is a task well suited for AI — and these tools require that every detail of an experiment be structured and recorded in order to generate meaningful insights. Yatsenko says the latest advances in the DataJoint platform unify an experiment’s design, code, and data — creating a structure that both humans and AI systems can interpret. “For labs seeking rigor, reproducibility, and AI readiness, DataJoint offers a path to organize complexity and unlock the full value of their data.”

    Schedule a Call with the DataJoint Team:
    Ready to transform your lab’s productivity, reproducibility, and impact? Schedule a conversation with our team to discover how DataJoint can accelerate your research and give your lab a competitive edge.

  • Data needs direction: five clarifications for database design

    Data needs direction: five clarifications for database design

    Sometimes a new computational paradigm can be better defined by abolishing distracting capabilities than by adding new capabilities. For example, Edsger Dijkstra paved the way for structured programming by arguing for abolishing the use of GOTO statements in programming languages (see his 1968 letter “Go To Statement Considered Harmful”). The constructs for structured programming had already existed but the paradigm shift needed the extra push by stamping out the anti-patterns enabled by GOTOs.  Today’s high-level programming languages lack the very concept of GOTO.  

    DataJoint is a full-featured relational database programming language; it replaces SQL for defining and querying structured data. DataJoint implements a new form of the relational data model that is more semantically refined to make schema design clearer while retaining the full capabilities and rigor of the relational data model. It makes good design practices more obvious and bad design choices harder or impossible.

    In this story, let me illustrate five of DataJoint’s clarifications that make database work more rigorous and teachable.

    Clarification 1: Primary key not optional

    SQL sees no problem defining a table with no primary key thereby failing to enforce the foundational premise of the relational model that all tables must represent sets (unordered collections of unique elements). DataJoint’s syntax makes it impossible to not define a primary key.  For example, the table definition below is perfectly legal in SQL.

    CREATE TABLE person (
     person_id int,
     first_name varchar(30),
     last_name varchar(30))

    A better design would define the primary key and make the required columns not null, resulting in this longer code:

    CREATE TABLE person (
     person_id int NOT NULL,
     first_name varchar(30) NOT NULL,
     last_name varchar(30) NOT NULL,
     PRIMARY KEY (person_id))

    The same definition in DataJoint would appear as follows. We use Python as the host language in all examples.

    @schema
    class Person(dj.Manual):
       definition = """
       person_id : int
       ---
       first_name : varchar(30)
       last_name : varchar(30)
       """

    The divider — separates the primary key fields above from the secondary attributes below. There is no option to omit defining a primary key. All attributes are required by default and are not nullable. SQL made a terrible choice to make fields nullable by default.

    Clarification 2: Missing values, defaults, and nulls.

    The second clarification concerns the use of optional attributes. A field (or attribute) is optional if specifying its value is not required when inserting new data. In SQL, this is possible when either a default value is provided or the field is nullable. NULL is not just a special value; its logic is handled quite differently from all other values. A point of confusion is that in SQL a field can be nulllable and it may have a non-null default value.  

    For example, in the following definition the field quantity is both nullable and has a default value of 100.

    CREATE TABLE order_item (
     order_id int NOT NULL,
     item_id int NOT NULL,
     quantity int DEFAULT 100
     PRIMARY_KEY (order_id, item_id),
     FOREIGN KEY (order_id) REFERENCES order (order_id),
     FOREIGN KEY (item_id) REFERENCES item (item_id))

    Then an  INSERT omit a value would result in the use of the default value of 100. The client would also have the option to insert NULL to indicate the missing value. This creates many confusing choices and behaviors. While this abundance of choices may find its use, more often than not, it multiplies confusion as we must juggle multiple definitions of the term “missing value.”

    In DataJoint, one makes a field nullable by setting its default to null.  This sidesteps many problems of definitions and use of missing values.

    The behavior is simple: if a value is missing, then the default is used. If the default is null, then the value is nullable. You can use either of two definitions:

    # Definition 1
    @schema
    class OrderItem(dj.Manual):
       definition = """
       -> Order
       -> Item
       ---
       quantity = 100 : int
       """

    or

    # Definition 2
    @schema
    class OrderItem(dj.Manual):
       definition = """
       -> Order
       -> Item
       ---
       quantity = null : int
       """

    In the first definition, quantity is not nullable and defaults to 100; in the second, it is nullable and it defaults to null. We give up the flexibility to provide a non-null default to a nullable field but it’s a sacrifice well worth the clarify of definitions, communication, and insert behavior.

    As an aside, in general, the number of nullable attributes should be small in well-designed schemas. If many attributes are nullable, this probably means that they are defined in the wrong table and an extra table must be defined to represent entities for which these attributes are required and therefore not nullable.

    Clarification 3: Foreign keys reference the primary key

    Nearly always, the foreign key must reference the primary key attributes of the parent table and the foreign key attributes in the child table must have the same types as the primary key attributes in the parent table, listed in the same order in the foreign key declaration. That’s quite a bit of complexity to track. Yet SQL syntax makes no effort to simplify this most common use. The syntax for an invalid foreign key referencing a secondary non-unique attribute is indistinguishable from a well-formed foreign key. Changing the primary key in the primary key requires concomitant changes of all the foreign key attributes in all the referencing child tables.

    DataJoint abolishes this complexity by requiring the foreign key to always reference the primary key and automatically introduces required foreign key attributes with correctly matching definitions.  Let’s define the table FilledItem referencing the OrderItem table defined above.

    SQL first:

    CREATE TABLE filled_item (
     order_id int NOT NULL,
     item_id int NOT NULL,
     fill_date  date NOT NULL,
     PRIMARY KEY (order_id, item_id),
     FOREIGN KEY (order_id, item_id) REFERENCES order_item(order_id, item_id)
    )

    The equivalent definition in DataJoint is

    @schema
    class FilledItem(dj.Manual):
       definition = """
       -> OrderItem
       ---
       fill_date : date
       """

    DataJoint removes the flexibility to define foreign keys referencing anything other than the primary key but greatly simplifies both the syntax, shortens the learning process, and reduces opportunities for error.

    Clarification 4: No cyclic dependencies

    One of the most significant simplifications in DataJoint is the elimination of cyclic dependencies in database schemas. All database schemas designed with DataJoint must constitute Directed Acyclic Graphs (DAGs).

    To illustrate, let’s consider the Sakila database for a DVD rental shop provided in the MySQL documentation and used by many tutorials.

    Here is its Enhanced Entity Relationship Diagram:

    The schema has a cyclic dependency. Can you spot it?

    After setting up the database, we can connect to it with DataJoint and interact with its individual tables.

    Screen Shot 2021-09-28 at 11.51.39 AM.png

    However, when attempting to plot the Diagram, DataJoint raises the error indicating that it cannot handle cyclic dependencies.

    Screen Shot 2021-09-28 at 12.00.43 PM.png

    The cycle is introduced between the staff and store tables where each staff references the store and each store references its manager from the staff.

    To break the cycle, we drop the manager foreign key and plot the diagram.

    DataJoint Diagram of the Sakila Database

    In Jupyter, hovering over the tables in the diagram will show their detailed definitions in DataJoint declaration notation.

    Compare the EER diagram above and the DataJoint diagram. What stands out? Which is more amenable for rapid comprehension?

    DataJoint schema designs have a direction. To populate the data, you start from the top of the diagram and move down step by step. In this way, the database schema also expresses the workflow for data collection and analysis. Having worked with hundreds of DataJoint schemas for 13 years, it now pains me to have to figure out a non-directional schema as shown in the conventional EER above. Databases need a sense of direction to help orient their users and designers.

    But did we lose any representational power? Is there a way to represent managers for stores referencing the staff? It turns out that any cyclic dependency can be replaced with an equivalent acyclic design, which may require an additional to represent the relationship.

    Thus we add the table StoreManager to the schema:

    @schema
    class StoreManager(dj.Manual):
       definition = """
       -> Store
       ---
       -> Staff
       """

    And the diagram beccomes

    DataJoint schema diagram for the updated Sakila database

    The updated schema has an extra table to represent the store managers without a cyclic dependency, enforcing the same constraints as the original schema.

    Clarification 5. Rows are immutable: no UPDATE (normally)

    In the original cyclic schema for the Sakila database, it was not possible to populate the Store and Staff tables with INSERTs alone when foreign keys are enforced.  To populate Staff, one must have a Store and vice versa. Therefore, it would be necessary to make one of the foreign keys nullable, populate the table with NULL for the reference. After the other table is populated, then you would need to use UPDATE queries to fix the reference.

    For example, we could first populate the Store table putting NULL for the manager references.  Then we would populate the Staff table and then go back and use UPDATE to set the managers for the Store.

    This problem does not exist for the acyclic design. One first populates the Store table, then the Staff referencing the Store, and finally populating the StoreManager table referencing both.

    Therefore, the final key simplification of the DataJoint model is the assumption that tuples (or rows) in tables are immutable.  They can be inserted or deleted but not updated.

    The UPDATE operation is not used in normal operation. It still exists but it is understood that UPDATE is used for deliberate corrective operations, to fix mistakes but not as a normal operation in the regular workflow.

    The assumption that tuples are immutable serves as the foundation for the data dependency model since foreign keys express dependencies between tuples (or entities) in the tables not simply between individual fields as is often assumed in SQL.

    Summary

    Sometimes less is more. By bad choices  less available available, DataJoint brings focus, increases productivity, and improves communication. The result is a modern take on the relational model for the next generation of scientific computing projects.

  • Optional dependencies

    When a foreign key is a secondary attribute, its value may made optional in one of three ways.

    Let’s say that an attribute of the entity set Student is the student’s major and the valid majors are in Major. We need to allow for students with and without majors. Here are the three ways to define this relationship with their respective strengths and weaknesses.

    Solution 1: Make the foreign key nullable

    Definition of nullable foreign keys is described in docs.datajoint.io. However, this feature is only scheduled for release in the upcoming datajoint-python version 0.11.

    The definitions of the two tables would appear as follows:

    :: Major

    major  : char(8)    # abberviated name, e.g. BIOL, PHYS, NEUROSCI

    ---

    major_name  : varchar(255)  # full major name

    -> Department

    :: Student

    student_id  : int

    ---

    full_name     : varchar(255)   #  e.g.  DOE, Jane S

    date_of_birth : date

    sex           : enum('M','F','U')

    -> [nullable] Major

    Solution 2: A separate association table

    If an attribute or attributes are optional, sometimes it makes more sense to put them in a separate dependent table. For the example above, we would leave out the major from the student table and add a new table StudentMajor to associate a student with a major:

    :: Student

    student_id  int

    ---

    full_name     : varchar(255)   #  e.g.  DOE, Jane S

    date_of_birth : date

    sex           : enum('M','F','U')

    :: StudentMajor

    -> Student

    ---

    -> Major

    Solution 3: Special value

    Finally, one could keep the dependency required but add a special value to Major to indicate missing major, for example, ‘NONE’ or ‘UNDECL’.

    Then Student will be declared as

    :: Student

    student_id  : int

    ---

    full_name     : varchar(255)   #  e.g.  DOE, Jane S

    date_of_birth : date

    sex           : enum('M','F','U')

    -> Major

    Which solution is best?

    Right away, let’s state that Solution 3 is rarely optimal. Special values to indicate missing values are generally considered poor technique because they require additional implicit semantics and rules. However, when such special values are institutionalized, this choice may be justified.

    The choice between Solutions 1 and 2 may depend on other considerations. For example, if an attribute may change its value, it may be better to place it in a separate table as in Solution 2 rather than to keep it together with the permanent attributes. For example, can a student declare her major or change her major later on? Under Solution 1, changing the major would require an update of the existing student record. In contrast, under Solution 2, the major can be changed without perturbing Student.

    In DataJoint, tuples are considered immutable and the proper way to manipulate data is through inserts and deletes rather than updates. Even though updates are implemented, they are more of a workaround for special cases.

    Since Solution 2, has always been available, we are only now getting around to implement nullable foreign keys for Solution 1.

    If the optional attribute is indeed permanent, then Solution 1 may be preferable because it saves us an extra table and potentially simplifies some queries. However, as always, dealing with NULL values may lead to some counterintuitive results in queries involving comparisons. Intuitive implementation of operators involving NULLs is what has kept me from promoting nullable foreign keys. We are working to define them more most logically.

    For example, the results of Student - Major under Solution 1, would always produce the empty set with the current implementation of restriction since MySQL’s IN and NOT IN operators always yield NULL when testing NULL values. We will fix the logic so that Student - Major would yield students where major is NULL.

  • Aggregation functions within restriction conditions

    Example 1: global argmax

    Restricting a relation to a subset based on the average or maximum value of some attribute seems like it should be an easy operation.

    For example, consider the table with heading

    Student: (student*, height)

    Now let’s select the tallest student.

    You may attempt the following in DataJoint:

    Student & 'height=max(height)'

    or in SQL:

    SELECT student

    WHERE height=max(height)

    However, both fail. Aggregation functions such as max, sum, or avg are not allowed in restrictions. Restrictions apply to each row and all their functions must operate on attributes in that row and they cannot examine other rows.

    Therefore, in DataJoint (version 0.10.0+), the solution would be

    Student * dj.U().aggr(

       Student, 'max_height=max(height)'

       ) & 'height=max_height'

    We can break this expression up into three steps:

    m = dj.U().aggr(Student, max_height='max(height)')

    s = Student * m

    r = s & 'height=max_height'

    The first expression uses dj.U() (the relation with one row and zero attributes) to aggregate the maximum height. The resulting relation m has a single non-primary attribute `max_height` and one row with the highest value of height.

    The second expression joins max_height to every row in Student. Now every row has both the height and the maximum height and we are ready for the restriction in the final step.

    The literal translation into SQL would be

    SELECT

       student, height

    FROM

       Student NATURAL JOIN

           (

           SELECT

               max(height) as max_height

           FROM

               Student

           ) as m

    WHERE

       height = max_height

    However, SQL also allows using results of subqueries as scalars in WHERE clauses, allowing a simpler expression

    SELECT

       student, height

    FROM

       Student

    WHERE

       height = (SELECT max(height) FROM Student)

    Example 2: Group average

    Let’s use the tables Enroll listing students in each course and Course listing all coures.

    Enroll: (course*, student*)

    Course: (course*, course_description)

    Let’s find all students above average height in each course.

    Again, a naive query might look something like

    1

    Enroll * Student & 'height > avg(height)'

    This fails for the same reason: aggregation functions are not allowed in restriction expressions.

    Again, we must first compute the averages per course and join them into the original expression before restriction:

    # extend Enroll with student height

    e = Enroll * Student  

    # average height in each course

    h = Course.aggr(e, avg_height='avg(height)')  

    # extend enrollment with average height per course

    s = e * h

    # restrict enrollment to above-average-height students

    r = s & 'height>avg_height'  

    Or, more succinctly,

    e = Enroll * Student  

    r = e * Course.aggr(e, avg_height='avg(height)')

       & 'height>avg_height'

    An efficient equivalent expression in SQL could be:

    SELECT

       course, student, height

    FROM

       Enroll NATURAL JOIN Student NATURAL JOIN (

           SELECT

               course, avg(height) as avg_height

           FROM

               Enroll NATURAL JOIN Student

           GROUP BY course) as h

    WHERE

       height > avg_height

  • Strong Entity Integrity: Part 7 — Division

    One of the most difficult relational operations to comprehend is the relational division.

    We re-define division as

    Division B ÷ C with respect to A is the subset of A for which every matching element in C has a match in B.

    In DataJoint, relational division is performed by the following expression:

    D = A - (A*C - B)

    Most traditional definitions also exclude the non-primary attributes from the result, making it equivalent to

    D = A.proj() - (A*C - B)

    From this definition, it follows that relational division is a form of restriction on A and it preserves its entity class and primary key.

    The reason that the traditional formulations of relational division are so difficult to articulate is that they present division as a binary operator on B and C, introducing A implicitly through operations on the relations’ headings. DataJoint requires that A be explicitly formed. Therefore, division in DataJoint is a ternary operator.

    As an example, consider the following fragment of a university database (in Python):

    @schema

    class StudentMajor(dj.Manual):

       definition = """  # Student with major

       -> Student

       ---

       -> Major

       """

    @schema

    class CompletedCourse(dj.Manual):

       definition = """  # Student's completed course

       -> Student

       -> Course

       ---

       -> Grade

       """

    @schema

    class RequiredCourse(dj.Manual):

       definition = """  # Course required for major

       -> Major

       -> Course

       """

    Then the division CompletedCourse ÷ RequiredCourse with respect to StudentMajor is the list of all students with majors who have completed all the courses required for their major.

    required_courses = StudentMajor()*RequiredCourse()

    remaining_courses = required_courses - CompletedCourse()

    candidates = StudentMajor() - remaining_courses

    or as a single statement:

    candidates = StudentMajor() - (

       StudentMajor()*RequiredCourse() - CompletedCourse())

    Advanced: The conventional binary relational division can be mimicked using DataJoint’s special universal entity set dj.U by replacing A = dj.U(B.primary_key – C.primary_key) & B().

  • Strong Entity Integrity: Part 6 — Semijoin and antijoin

    Argh, semijoins and antijoins are misnamed.

    There is a zoo of joins in relational algebra (and SQL): cross join, equijoin, natural join, inner join, theta join, left join, and outer join. They follow a pattern: they have all the attributes of its operands. Semijoins and antijoins are different. They have only the attributes and the tuples from their left argument. Indeed, semijoins and antijoins are a form of restriction (or selection).

    In DataJoint, the terms semijoins and antijoins are not used to avoid the confusion. Both these operators fit the definition of the restriction operator. DataJoint uses the same operators & and – as for other forms of restriction.

    Therefore, the Strong Entity Integrity considerations for these operators are the same as in restriction.

    However, there is something in common with the join: the join compatibility rules. Restriction by another relation should only be performed on attributes that are in the primary key or a foreign key in both operands: they must be part of the identifying attributes that is used to identify and match entities across different entity sets.

  • Strong Entity Integrity: Part 5 — Aggregation

    DataJoint’s principle of Strong Entity Integrity (SEI) requires that queries must not introduce new classes of entities: projection and restriction operators preserve the entity class of its operand whereas the join operator yields a new entity class but one comprising the combination of the entity classes of its operands. A DataJoint query make obvious the entity class of its result.

    One operator that most egregiously violates this principle in relational algebra and SQL is the aggregation operator also known as GROUP BY. In its traditional formulation, aggregation allows performing summary operations on groups of tuples identified by a combination of grouping attributes. The effective primary key of the result are the grouping attributes. Therefore the query creates a new type of entity in the middle of a query that is not traced to any explicitly defined entity class. SQL allows a further deviation from entity integrity with its ROLLUP functionality producing results comprising mixtures of entity classes with different primary keys.

    DataJoint respects SEI and defines aggregation as a binary operator allowing summary operations on subsets of entity set B grouped by entities from class A. It has the following notation: A.aggr(B, …') where … is a list of aggregation computations such as n='sum(attr)`. In this way aggregation is a form of projection, preserving the entity class of A.

    A.aggr(B, …) is equivalent to SELECT … FROM B GROUP BY . As always, the primary key cannot be omitted.

    DataJoint simply makes explicit what programmers imply implicitly when they perform a GROUP BY operation. When grouping, we conceive of some sort of entity represented by the grouping attributes. In most cases, that entity class is already defined, often in the form of a table. Yet SQL forces users to spell out the list of attributes rather than explicitly specify the aggregating entity set.

    For example, consider the following table definition for college course grades:

    @schema

    class Grade(dj.Manual):

       definition = """

       -> Student

       -> Course

       ---

       grade: decimal(3, 2)  # grade e.g. 3.67

       """

    Then studentss GPA can be computed as

    Student().aggr(Grade(), gpa='AVG(grade)')

    The entity class of the result is the same as that of the aggregating entity: the result is still a set entities of class Student.