Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Relational algebra
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Theory of relational databases}} {{Distinguish|Relation algebra}} In [[database theory]], '''relational algebra''' is a theory that uses [[algebraic structure]]s for modeling data and defining queries on it with well founded [[semantics (computer science)|semantics]]. The theory was introduced by [[Edgar F. Codd]].<ref name="Codd1970">{{cite journal|first=E.F.|last=Codd|author-link=E.F. Codd|title=A Relational Model of Data for Large Shared Data Banks|journal=[[Communications of the ACM]]|volume=13|issue=6|date=1970|pages=377β387| doi = 10.1145/362384.362685|s2cid=207549016 |doi-access=free}}</ref> The main application of relational algebra is to provide a theoretical foundation for [[relational database]]s, particularly [[query language]]s for such databases, chief among which is [[SQL]]. Relational databases store tabular data represented as [[relation (database)|relations]]. Queries over relational databases often likewise return tabular data represented as relations. The main purpose of relational algebra is to define [[Operator (mathematics)|operators]] that transform one or more input relations to an output relation. Given that these operators accept relations as input and produce relations as output, they can be combined and used to express complex queries that transform multiple input relations (whose data are stored in the database) into a single output relation (the query results). [[Unary operator]]s accept a single relation as input. Examples include operators to filter certain attributes (columns) or [[tuple]]s (rows) from an input relation. [[Binary operator]]s accept two relations as input and combine them into a single output relation. For example, taking all tuples found in either relation ([[Union (set theory)|union]]), removing tuples from the first relation found in the second relation ([[Difference (set theory)|difference]]), extending the tuples of the first relation with tuples in the second relation matching certain conditions, and so forth. == Introduction == Relational algebra received little attention outside of pure mathematics until the publication of [[Edgar F. Codd|E.F. Codd]]'s [[relational model|relational model of data]] in 1970.<ref>{{Cite journal |last=Maddux |first=Roger D. |date=1991-09-01 |title=The origin of relation algebras in the development and axiomatization of the calculus of relations |url=https://link.springer.com/article/10.1007/BF00370681 |journal=Studia Logica |language=en |volume=50 |issue=3 |pages=421β455 |doi=10.1007/BF00370681 |issn=1572-8730}}</ref> Codd proposed such an algebra as a basis for database query languages. Relational algebra operates on homogeneous sets of tuples <math>S = \{(s_{j1},s_{j2}, ... s_{jn}) | j \in 1 ... m \} </math> where we commonly interpret ''m'' to be the number of rows of tuples in a table and ''n'' to be the number of columns. All entries in each column have the same [[data domain|type]]. A relation also has a unique tuple called the '''header''' which gives each column a unique name or '''attribute''' inside the relation. Attributes are used in projections and selections. == Set operators == {{main|Set theory}} The relational algebra uses [[set union]], [[set difference]], and [[Cartesian product]] from set theory, and adds additional constraints to these operators to create new ones. For set union and set difference, the two [[relation (database)|relation]]s involved must be ''union-compatible''βthat is, the two relations must have the same set of attributes. Because [[set intersection]] is defined in terms of set union and set difference, the two relations involved in set intersection must also be union-compatible. For the Cartesian product to be defined, the two relations involved must have disjoint headersβthat is, they must not have a common attribute name. In addition, the Cartesian product is defined differently from the one in [[Set (mathematics)|set]] theory in the sense that tuples are considered to be "shallow" for the purposes of the operation. That is, the Cartesian product of a set of ''n''-tuples with a set of ''m''-tuples yields a set of "flattened" {{math|(''n'' + ''m'')}}-tuples (whereas basic set theory would have prescribed a set of 2-tuples, each containing an ''n''-tuple and an ''m''-tuple). More formally, ''R'' Γ ''S'' is defined as follows: <math display=block>R\times S:=\{(r_1,r_2,\dots,r_n,s_1,s_2,\dots,s_m)|(r_1,r_2,\dots,r_n)\in R, (s_1,s_2,\dots,s_m)\in S\}</math> The cardinality of the Cartesian product is the product of the cardinalities of its factors, that is, |''R'' Γ ''S''| = |''R''| Γ |''S''|. == Projection == {{Main|Projection (relational algebra)}} A '''projection''' ({{math|Π}}) is a [[unary operation]] written as <math>\Pi_{a_1, \ldots,a_n}( R )</math> where <math>a_1,\ldots,a_n</math> is a set of attribute names. The result of such projection is defined as the [[Set (mathematics)|set]] that is obtained when all [[tuple]]s in ''R'' are restricted to the set <math>\{a_1,\ldots,a_n\}</math>. Note: when implemented in [[SQL]] standard the "default projection" returns a [[multiset]] instead of a set, and the {{math|Π}} projection to eliminate duplicate data is obtained by the addition of the [[Select (SQL)|<code>DISTINCT</code> keyword]]. == Selection == {{Main|Selection (relational algebra)}} A '''generalized selection''' (σ) is a [[unary operation]] written as <math>\sigma_\varphi(R)</math> where {{Ο}} is a [[propositional formula]] that consists of [[atomic formula|atom]]s as allowed in the [[selection (relational algebra)|normal selection]] and the logical operators {{and}} ([[logical conjunction|and]]), {{or-}} ([[logical disjunction|or]]) and {{Not}} ([[negation]]). This selection selects all those [[tuple]]s in ''R'' for which {{Ο}} holds. To obtain a listing of all friends or business associates in an address book, the selection might be written as <math>\sigma_{\text{isFriend = true} \,\lor\, \text{isBusinessContact = true}}( \text{addressBook} )</math>. The result would be a relation containing every attribute of every unique record where {{math|size=90%|isFriend}} is true or where {{math|size=90%|isBusinessContact}} is true. == Rename == {{Main|Rename (relational algebra)}} A '''rename''' (''Ο'') is a [[unary operation]] written as <math>\rho_{a / b}(R)</math> where the result is identical to ''R'' except that the ''b'' attribute in all tuples is renamed to an ''a'' attribute. This is commonly used to rename the attribute of a [[relation (database)|relation]] for the purpose of a join. To rename the "isFriend" attribute to "isBusinessContact" in a relation, <math>\rho_{\text{isBusinessContact / isFriend} } ( \text{addressBook} )</math> might be used. There is also the <math>\rho_{x(A_1, \ldots,A_n)}(R)</math> notation, where ''R'' is renamed to ''x'' and the attributes <math>\{a_1,\ldots,a_n\}</math> are renamed to <math>\{A_1,\ldots,A_n\}</math>.<ref>{{Cite book|last=Silberschatz|first=Abraham |title=Database system concepts|date=2020 |author2=Henry F. Korth |author3=S. Sudarshan|isbn=978-0-07-802215-9|edition=Seventh |location=New York |oclc=1080554130|page=56}}</ref> == Joins and join-like operators == {{split section|Join (relational algebra)|discuss={{TALKPAGENAME}}#Split join into its own article |date=March 2023}} === Natural join === {{redirect|Natural join|the SQL implementation|Natural join (SQL)}} {{redirect|β|the band sometimes represented by this symbol|The Armed}} Natural join (β¨) is a [[Binary relation|binary operator]] that is written as (''R'' β¨ ''S'') where ''R'' and ''S'' are [[relation (database)|relation]]s.{{efn|In [[Unicode]], the join symbol is β¨ (U+2A1D), and the bowtie symbol, occasionally used instead, is β (U+22C8).}} The result of the natural join is the set of all combinations of tuples in ''R'' and ''S'' that are equal on their common attribute names. For an example consider the tables ''Employee'' and ''Dept'' and their natural join:{{citation needed|date=April 2022}} {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Sales |- | Mary || 1257 || Human Resources |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Finance || George |- | Sales || Harriet |- | Production || Charles |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β¨ ''Dept'' |- ! Name !! EmpId !! DeptName !! Manager |- | Harry || 3415 || Finance || George |- | Sally || 2241 || Sales || Harriet |- | George || 3401 || Finance || George |- | Harriet || 2202 || Sales || Harriet |} {{col-end}} Note that neither the employee named Mary nor the Production department appear in the result. Mary does not appear in the result because Mary's Department, "Human Resources", is not listed in the Dept relation and the Production department does not appear in the result because there are no tuples in the Employee relation that have "Production" as their DeptName attribute. This can also be used to define [[composition of relations]]. For example, the composition of ''Employee'' and ''Dept'' is their join as shown above, projected on all but the common attribute ''DeptName''. In [[category theory]], the join is precisely the [[fiber product]]. The natural join is arguably one of the most important operators since it is the relational counterpart of the logical AND operator. Note that if the same variable appears in each of two predicates that are connected by AND, then that variable stands for the same thing and both appearances must always be substituted by the same value (this is a consequence of the [[idempotence]] of the logical AND). In particular, natural join allows the combination of relations that are associated by a [[foreign key]]. For example, in the above example a foreign key probably holds from ''Employee''.''DeptName'' to ''Dept''.''DeptName'' and then the natural join of ''Employee'' and ''Dept'' combines all employees with their departments. This works because the foreign key holds between attributes with the same name. If this is not the case such as in the foreign key from ''Dept''.''Manager'' to ''Employee''.''Name'' then these columns must be renamed before taking the natural join. Such a join is sometimes also referred to as an '''equijoin'''. More formally the semantics of the natural join are defined as follows: {{NumBlk|:|<math>R \bowtie S = \left\{ r \cup s \ \vert \ r \in R \ \land \ s \in S \ \land \ \mathit{Fun}(r \cup s) \right\}</math>|{{EquationRef|1}}}} where ''Fun(t)'' is a [[Predicate (mathematics)|predicate]] that is true for a [[Relation (mathematics)|relation]] ''t'' (in the mathematical sense) [[iff]] ''t'' is a function (that is, ''t'' does not map any attribute to multiple values). It is usually required that ''R'' and ''S'' must have at least one common attribute, but if this constraint is omitted, and ''R'' and ''S'' have no common attributes, then the natural join becomes exactly the Cartesian product. The natural join can be simulated with Codd's primitives as follows. Assume that ''c''<sub>1</sub>,...,''c''<sub>''m''</sub> are the attribute names common to ''R'' and ''S'', ''r''<sub>1</sub>,...,''r''<sub>''n''</sub> are the attribute names unique to ''R'' and ''s''<sub>1</sub>,...,''s''<sub>''k''</sub> are the attribute names unique to ''S''. Furthermore, assume that the attribute names ''x''<sub>1</sub>,...,''x''<sub>''m''</sub> are neither in ''R'' nor in ''S''. In a first step the common attribute names in ''S'' can be renamed: {{NumBlk|:|<math>T = \rho_{x_1/c_1,\ldots,x_m/c_m}(S) = \rho_{x_1/c_1}(\rho_{x_2/c_2}(\ldots\rho_{x_m/c_m}(S)\ldots))</math>|{{EquationRef|2}}}} Then we take the Cartesian product and select the tuples that are to be joined: {{NumBlk|:|<math>P = \sigma_{c_1=x_1,\ldots,c_m=x_m}(R \times T) = \sigma_{c_1=x_1}(\sigma_{c_2=x_2}(\ldots\sigma_{c_m=x_m}(R \times T)\ldots))</math>|{{EquationRef|3}}}} Finally we take a projection to get rid of the renamed attributes: {{NumBlk|:|<math>U = \Pi_{r_1,\ldots,r_n,c_1,\ldots,c_m,s_1,\ldots,s_k}(P)</math>|{{EquationRef|4}}}} === ''ΞΈ''-join and equijoin === Consider tables ''Car'' and ''Boat'' which list models of cars and boats and their respective prices. Suppose a customer wants to buy a car and a boat, but she does not want to spend more money for the boat than for the car. The ''ΞΈ''-join (β<sub>''ΞΈ''</sub>) on the predicate ''CarPrice'' β₯ ''BoatPrice'' produces the flattened pairs of rows which satisfy the predicate. When using a condition where the attributes are equal, for example Price, then the condition may be specified as ''Price''=''Price'' or alternatively (''Price'') itself. {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Car'' |- ! CarModel !! CarPrice |- | CarA || 20,000 |- | CarB || 30,000 |- | CarC || 50,000 |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Boat'' |- ! BoatModel !! BoatPrice |- | Boat1 || 10,000 |- | Boat2 || 40,000 |- | Boat3 || 60,000 |} {{col-break|gap=2em}} {| class="wikitable" |+ <math>{ Car \bowtie Boat \atop \scriptstyle CarPrice \geq BoatPrice }</math> |- ! CarModel !! CarPrice !! BoatModel !! BoatPrice |- | CarA || 20,000 || Boat1 || 10,000 |- | CarB || 30,000 || Boat1 || 10,000 |- | CarC || 50,000 || Boat1 || 10,000 |- | CarC || 50,000 || Boat2 || 40,000 |} {{col-end}} In order to combine tuples from two relations where the combination condition is not simply the equality of shared attributes it is convenient to have a more general form of join operator, which is the ''ΞΈ''-join (or theta-join). The ''ΞΈ''-join is a binary operator that is written as <math>{R\ \bowtie\ S \atop a\ \theta\ b}</math> or <math>{R\ \bowtie\ S \atop a\ \theta\ v}</math> where ''a'' and ''b'' are attribute names, ''ΞΈ'' is a binary [[relational operator]] in the set {{math|1 = {<, β€, =, β , >, β₯}}}, ''Ο '' is a value constant, and ''R'' and ''S'' are relations. The result of this operation consists of all combinations of tuples in ''R'' and ''S'' that satisfy ''ΞΈ''. The result of the ''ΞΈ''-join is defined only if the headers of ''S'' and ''R'' are disjoint, that is, do not contain a common attribute. The simulation of this operation in the fundamental operations is therefore as follows: : ''R'' β<sub>''ΞΈ''</sub> ''S'' = ''Ο<sub>ΞΈ</sub>''(''R'' Γ ''S'') In case the operator ''ΞΈ'' is the equality operator (=) then this join is also called an '''equijoin'''. Note, however, that a computer language that supports the natural join and selection operators does not need ''ΞΈ''-join as well, as this can be achieved by selection from the result of a natural join (which degenerates to Cartesian product when there are no shared attributes). In SQL implementations, joining on a predicate is usually called an ''inner join'', and the ''on'' keyword allows one to specify the predicate used to filter the rows. It is important to note: forming the flattened Cartesian product then filtering the rows is conceptually correct, but an implementation would use more sophisticated data structures to speed up the join query. === Semijoin === The left semijoin (β and β) is a joining similar to the natural join and written as <math alt="π β π">R \ltimes S</math> where <math alt="π ">R</math> and <math alt="π">S</math> are [[relation (database)|relation]]s.{{efn|In [[Unicode]], the ltimes symbol is β (U+22C9). The rtimes symbol is β (U+22CA)}} The result is the set of all tuples in <math alt="π ">R</math> for which there is a tuple in <math alt="π">S</math> that is equal on their common attribute names. The difference from a natural join is that other columns of <math alt="π">S</math> do not appear. For example, consider the tables ''Employee'' and ''Dept'' and their semijoin:{{citation needed|date=April 2022}} {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Production |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Sales || Sally |- | Production|| Harriet |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β ''Dept'' |- ! Name !! EmpId !! DeptName |- | Sally || 2241 || Sales |- | Harriet || 2202 || Production |} {{col-end}} More formally the semantics of the semijoin can be defined as follows: <math alt="π β π = { π‘ : π‘ β π β§β β π β π(Fun(π‘ β© π ))}">R \ltimes S = \{ t : t \in R \land \exists s \in S(\operatorname{Fun}(t \cup s)) \}</math> where <math alt="Fun(π)">\operatorname{Fun}(r)</math> is as in the definition of natural join. The semijoin can be simulated using the natural join as follows. If <math alt="a<sub>1</sub>, ..., a<sub>n</sub>">a_1, \ldots, a_n</math> are the attribute names of <math alt="π ">R</math>, then <math alt="π β π = Ξ _{a<sub>1</sub>, ..., a<sub>n</sub>} (π β π)">R \ltimes S = \Pi_{a_1, \ldots, a_n}(R \bowtie S).</math> Since we can simulate the natural join with the basic operators it follows that this also holds for the semijoin. In Codd's 1970 paper, semijoin is called restriction.<ref name="Codd1970" /> === Antijoin === The antijoin (β·), written as ''R'' β· ''S'' where ''R'' and ''S'' are [[relation (database)|relation]]s,{{efn|In [[Unicode]], the Antijoin symbol is β· (U+25B7).}} is similar to the semijoin, but the result of an antijoin is only those tuples in ''R'' for which there is ''no'' tuple in ''S'' that is equal on their common attribute names.<ref name=unnesting>{{Cite conference |title=Unnesting Arbitrary Queries |conference=BTW |last=Neumann |first=Thomas |url=https://dl.gi.de/handle/20.500.12116/2418 |year=2015 |doi=}}</ref> For an example consider the tables ''Employee'' and ''Dept'' and their antijoin: {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Production |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Sales || Sally |- | Production || Harriet |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β· ''Dept'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | George || 3401 || Finance |} {{col-end}} The antijoin is formally defined as follows: : {{math|1 =''R'' β· ''S'' = { ''t'' : ''t'' β ''R'' ∧ Β¬∃''s'' β ''S''(''Fun'' (''t'' ∪ ''s'')) }}} or : {{math|1 = ''R'' β· ''S'' = { ''t'' : ''t'' β ''R'', there is no tuple ''s'' of ''S'' that satisfies ''Fun'' (''t'' ∪ ''s'') }}} where {{math|''Fun'' (''t'' ∪ ''s'')}} is as in the definition of natural join. The antijoin can also be defined as the [[Complement (set theory)|complement]] of the semijoin, as follows: {{NumBlk|:| {{math|1=''R'' β· ''S'' = ''R'' − ''R'' β ''S''}} |{{EquationRef|5}}}} Given this, the antijoin is sometimes called the anti-semijoin, and the antijoin operator is sometimes written as semijoin symbol with a bar above it, instead of β·. In the case where the relations have the same attributes (union-compatible), antijoin is the same as minus. === Division === The division (Γ·) is a binary operation that is written as ''R'' Γ· ''S''. Division is not implemented directly in SQL. The result consists of the restrictions of tuples in ''R'' to the attribute names unique to ''R'', i.e., in the header of ''R'' but not in the header of ''S'', for which it holds that all their combinations with tuples in ''S'' are present in ''R''. ==== Example ==== {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Completed'' |- ! Student !! Task |- | Fred || Database1 |- | Fred || Database2 |- | Fred || Compiler1 |- | Eugene || Database1 |- | Eugene || Compiler1 |- | Sarah || Database1 |- | Sarah || Database2 |} {{col-break|gap=2em}} {| class="wikitable" |+ ''DBProject'' |- ! Task |- | Database1 |- | Database2 |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Completed'' Γ· ''DBProject'' |- ! Student |- | Fred |- | Sarah |} {{col-end}}If ''DBProject'' contains all the tasks of the Database project, then the result of the division above contains exactly the students who have completed both of the tasks in the Database project. More formally the semantics of the division is defined as follows:{{NumBlk|:| {{math|''R'' Γ· ''S'' {{=}} { ''t''[''a''<sub>1</sub>,...,''a''<sub>''n''</sub>] : ''t'' β ''R'' β§ β''s'' β ''S'' ( (''t''[''a''<sub>1</sub>,...,''a''<sub>''n''</sub>] βͺ ''s'') β ''R'') } }} |{{EquationRef|6}}}}where {''a''<sub>1</sub>,...,''a''<sub>''n''</sub>} is the set of attribute names unique to ''R'' and ''t''[''a''<sub>1</sub>,...,''a''<sub>''n''</sub>] is the restriction of ''t'' to this set. It is usually required that the attribute names in the header of ''S'' are a subset of those of ''R'' because otherwise the result of the operation will always be empty. The simulation of the division with the basic operations is as follows. We assume that ''a''<sub>1</sub>,...,''a''<sub>''n''</sub> are the attribute names unique to ''R'' and ''b''<sub>1</sub>,...,''b''<sub>''m''</sub> are the attribute names of ''S''. In the first step we project ''R'' on its unique attribute names and construct all combinations with tuples in ''S'': : ''T'' := Ο<sub>''a''<sub>1</sub>,...,''a''<sub>''n''</sub></sub>(''R'') Γ ''S'' In the prior example, T would represent a table such that every Student (because Student is the unique key / attribute of the Completed table) is combined with every given Task. So Eugene, for instance, would have two rows, Eugene β Database1 and Eugene β Database2 in T. :: EG: First, let's pretend that "Completed" has a third attribute called "grade". It's unwanted baggage here, so we must project it off always. In fact in this step we can drop "Task" from R as well; the multiply puts it back on. :: ''T'' := Ο<sub>Student</sub>(''R'') Γ ''S'' // This gives us every possible desired combination, including those that don't actually exist in R, and excluding others (eg Fred | compiler1, which is not a desired combination) {{col-begin|width=auto; margin:0.5em auto}} {{col-break|gap=5em}} {| class="wikitable" |+ ''T'' |- ! Student !! Task |- | Fred || Database1 |- | Fred || Database2 |- | Eugene || Database1 |- | Eugene || Database2 |- | Sarah || Database1 |- | Sarah || Database2 |} {{col-end}} In the next step we subtract ''R'' from ''T'' [[relation (database)|relation]]: : ''U'' := ''T'' − ''R'' In ''U'' we have the possible combinations that "could have" been in ''R'', but weren't. :: EG: Again with projections β ''T'' and ''R'' need to have identical attribute names/headers. :: ''U'' := ''T'' − Ο<sub>Student,Task</sub>(''R'') // This gives us a "what's missing" list. {{col-begin|width=auto; margin:0.5em auto}} {{col-break|gap=5em}} {| class="wikitable" |+ ''T'' |- ! Student !! Task |- | Fred || Database1 |- | Fred || Database2 |- | Eugene || Database1 |- | Eugene || Database2 |- | Sarah || Database1 |- | Sarah || Database2 |} {{col-break|gap=2em}} {| class="wikitable" |+ ''R'' a.k.a. ''Completed'' |- ! Student !! Task |- | Fred || Database1 |- | Fred || Database2 |- | Fred || Compiler1 |- | Eugene || Database1 |- | Eugene || Compiler1 |- | Sarah || Database1 |- | Sarah || Database2 |} {{col-break|gap=2em}} {| class="wikitable" |+ ''U'' |+ aka |+ ''T'' − ''R'' |+ aka |+ ''what's missing'' |- ! Student !! Task |- | Eugene || Database2 |} {{col-end}} So if we now take the projection on the attribute names unique to ''R'' then we have the restrictions of the tuples in ''R'' for which not all combinations with tuples in ''S'' were present in ''R'': : ''V'' := Ο<sub>''a''<sub>1</sub>,...,''a''<sub>''n''</sub></sub>(''U'') :: EG: Project ''U'' down to just the attribute(s) in question (Student) :: ''V'' := Ο<sub>Student</sub>(''U'') {{col-begin|width=auto; margin:0.5em auto}} {{col-break|gap=5em}} {| class="wikitable" |+ ''V'' |- ! Student |- | Eugene |} {{col-end}} So what remains to be done is take the projection of ''R'' on its unique attribute names and subtract those in ''V'': : ''W'' := Ο<sub>''a''<sub>1</sub>,...,''a''<sub>''n''</sub></sub>(''R'') − ''V'' :: EG: ''W'' := Ο<sub>Student</sub>(''R'') − ''V''. {{col-begin|width=auto; margin:0.5em auto}} {{col-break|gap=5em}} {| class="wikitable" |+ Ο<sub>Student</sub>(''R'') |- ! Student |- | Fred |- | Eugene |- | Sarah |} {{col-break|gap=2em}} {| class="wikitable" |+ ''V'' |- ! Student |- | Eugene |} {{col-break|gap=2em}} {| class="wikitable" |+ ''W'' |+ aka |+ {{math|(Ο<sub>Student</sub>(''R'') − ''V'')}} |+ aka |+ desired result |- ! Student |- | Fred |- | Sarah |} {{col-end}} == Common extensions == In practice the classical relational algebra described above is extended with various operations such as outer joins, aggregate functions and even transitive closure.<ref name="ΓzsuValduriez2011">{{cite book|author1=M. Tamer Γzsu|author2=Patrick Valduriez|title=Principles of Distributed Database Systems|url=https://books.google.com/books?id=TOBaLQMuNV4C&pg=PA46|year=2011|publisher=Springer|isbn=978-1-4419-8833-1|page=46|edition=3rd}}</ref> === Outer joins === {{See also|Join (SQL)#Outer join}} Whereas the result of a join (or inner join) consists of tuples formed by combining matching tuples in the two operands, an outer join contains those tuples and additionally some tuples formed by extending an unmatched tuple in one of the operands by "fill" values for each of the attributes of the other operand. Outer joins are not considered part of the classical relational algebra discussed so far.<ref name="O'NeilO'Neil2001">{{cite book|author1=Patrick O'Neil|author2=Elizabeth O'Neil|author2-link=Elizabeth O'Neil|title=Database: Principles, Programming, and Performance, Second Edition|url=https://books.google.com/books?id=UXh4qTpmO8QC&pg=PA120|year=2001|publisher=Morgan Kaufmann|isbn=978-1-55860-438-4|page=120}}</ref> The operators defined in this section assume the existence of a ''null'' value, ''Ο'', which we do not define, to be used for the fill values; in practice this corresponds to the [[Null (SQL)|NULL]] in SQL. In order to make subsequent selection operations on the resulting table meaningful, a semantic meaning needs to be assigned to nulls; in Codd's approach the propositional logic used by the selection is [[Null (SQL)#Comparisons with NULL and the three-valued logic .283VL.29|extended to a three-valued logic]], although we elide those details in this article. Three outer join operators are defined: left outer join, right outer join, and full outer join. (The word "outer" is sometimes omitted.) ==== Left outer join ==== The left outer join (β) is written as ''R'' β ''S'' where ''R'' and ''S'' are [[relation (database)|relation]]s.{{efn|In [[Unicode]], the Left outer join symbol is β (U+27D5).}} The result of the left outer join is the set of all combinations of tuples in ''R'' and ''S'' that are equal on their common attribute names, in addition (loosely speaking) to tuples in ''R'' that have no matching tuples in ''S''.{{citation needed|date=April 2022}} For an example consider the tables ''Employee'' and ''Dept'' and their left outer join: {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Sales |- | Tim || 1123 || Executive |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Sales || Harriet |- | Production || Charles |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β ''Dept'' |- ! Name !! EmpId !! DeptName !! Manager |- | Harry || 3415 || Finance || Ο |- | Sally || 2241 || Sales || Harriet |- | George || 3401 || Finance || Ο |- | Harriet || 2202 || Sales || Harriet |- | Tim || 1123 || Executive || Ο |} {{col-end}} In the resulting relation, tuples in ''S'' which have no common values in common attribute names with tuples in ''R'' take a ''null'' value, ''Ο''. Since there are no tuples in ''Dept'' with a ''DeptName'' of ''Finance'' or ''Executive'', ''Ο''s occur in the resulting relation where tuples in ''Employee'' have a ''DeptName'' of ''Finance'' or ''Executive''. Let ''r''<sub>1</sub>, ''r''<sub>2</sub>, ..., ''r''<sub>''n''</sub> be the attributes of the relation ''R'' and let {(''Ο'', ..., ''Ο'')} be the singleton relation on the attributes that are ''unique'' to the relation ''S'' (those that are not attributes of ''R''). Then the left outer join can be described in terms of the natural join (and hence using basic operators) as follows: :<math>(R \bowtie S) \cup ((R - \pi_{r_1, r_2, \dots, r_n}(R \bowtie S)) \times \{(\omega, \dots, \omega)\})</math> ==== Right outer join ==== The right outer join (β) behaves almost identically to the left outer join, but the roles of the tables are switched. The right outer join of [[relation (database)|relation]]s ''R'' and ''S'' is written as ''R'' β ''S''.{{efn|In [[Unicode]], the Right outer join symbol is β (U+27D6).}} The result of the right outer join is the set of all combinations of tuples in ''R'' and ''S'' that are equal on their common attribute names, in addition to tuples in ''S'' that have no matching tuples in ''R''.{{citation needed|date=April 2022}} For example, consider the tables ''Employee'' and ''Dept'' and their right outer join: {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Sales |- | Tim || 1123 || Executive |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Sales || Harriet |- | Production || Charles |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β ''Dept'' |- ! Name !! EmpId !! DeptName !! Manager |- | Sally || 2241 || Sales || Harriet |- | Harriet || 2202 || Sales || Harriet |- | Ο || Ο || Production || Charles |} {{col-end}} In the resulting relation, tuples in ''R'' which have no common values in common attribute names with tuples in ''S'' take a ''null'' value, ''Ο''. Since there are no tuples in ''Employee'' with a ''DeptName'' of ''Production'', ''Ο''s occur in the Name and EmpId attributes of the resulting relation where tuples in ''Dept'' had ''DeptName'' of ''Production''. Let ''s''<sub>1</sub>, ''s''<sub>2</sub>, ..., ''s''<sub>''n''</sub> be the attributes of the relation ''S'' and let {(''Ο'', ..., ''Ο'')} be the singleton relation on the attributes that are ''unique'' to the relation ''R'' (those that are not attributes of ''S''). Then, as with the left outer join, the right outer join can be simulated using the natural join as follows: :<math>(R \bowtie S) \cup (\{(\omega, \dots, \omega)\} \times (S - \pi_{s_1, s_2, \dots, s_n}(R \bowtie S)))</math> ==== Full outer join ==== The '''outer join''' (β) or '''full outer join''' in effect combines the results of the left and right outer joins. The full outer join is written as ''R'' β ''S'' where ''R'' and ''S'' are [[relation (database)|relation]]s.{{efn|In [[Unicode]], the Full Outer join symbol is β (U+27D7).}} The result of the full outer join is the set of all combinations of tuples in ''R'' and ''S'' that are equal on their common attribute names, in addition to tuples in ''S'' that have no matching tuples in ''R'' and tuples in ''R'' that have no matching tuples in ''S'' in their common attribute names.{{citation needed|date=April 2022}} For an example consider the tables ''Employee'' and ''Dept'' and their full outer join: {{col-begin|width=auto; margin:0.5em auto}} {{col-break}} {| class="wikitable" |+ ''Employee'' |- ! Name !! EmpId !! DeptName |- | Harry || 3415 || Finance |- | Sally || 2241 || Sales |- | George || 3401 || Finance |- | Harriet || 2202 || Sales |- | Tim || 1123 || Executive |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Dept'' |- ! DeptName !! Manager |- | Sales || Harriet |- | Production || Charles |} {{col-break|gap=2em}} {| class="wikitable" |+ ''Employee'' β ''Dept'' |- ! Name !! EmpId !! DeptName !! Manager |- | Harry || 3415 || Finance || Ο |- | Sally || 2241 || Sales || Harriet |- | George || 3401 || Finance || Ο |- | Harriet || 2202 || Sales || Harriet |- | Tim || 1123 || Executive || Ο |- | Ο || Ο || Production || Charles |} {{col-end}} In the resulting relation, tuples in ''R'' which have no common values in common attribute names with tuples in ''S'' take a ''null'' value, ''Ο''. Tuples in ''S'' which have no common values in common attribute names with tuples in ''R'' also take a ''null'' value, ''Ο''. The full outer join can be simulated using the left and right outer joins (and hence the natural join and set union) as follows: :''R'' β ''S'' = (''R'' β ''S'') ∪ (''R'' β ''S'') === Operations for domain computations === There is nothing in relational algebra introduced so far that would allow computations on the data domains (other than evaluation of propositional expressions involving equality). For example, it is not possible using only the algebra introduced so far to write an expression that would multiply the numbers from two columns, e.g. a unit price with a quantity to obtain a total price. Practical query languages have such facilities, e.g. the SQL SELECT allows arithmetic operations to define new columns in the result <syntaxhighlight lang="sql" inline>SELECT unit_price * quantity AS total_price FROM t</syntaxhighlight>, and a similar facility is provided more explicitly by Tutorial D's <code>EXTEND</code> keyword.<ref name="Date2011">{{cite book|author=C. J. Date|title=SQL and Relational Theory: How to Write Accurate SQL Code|url=https://books.google.com/books?id=WuZGD5tBfMwC&pg=PA133|year=2011|publisher=O'Reilly Media, Inc.|isbn=978-1-4493-1974-8|pages=133β135}}</ref> In database theory, this is called '''extended projection'''.<ref name="Garcia-MolinaUllman2009"/>{{rp|213}} ==== Aggregation ==== Furthermore, computing various functions on a column, like the summing up of its elements, is also not possible using the relational algebra introduced so far. There are five [[aggregate function]]s that are included with most relational database systems. These operations are Sum, Count, Average, Maximum and Minimum. In relational algebra the aggregation operation over a schema (''A''<sub>1</sub>, ''A''<sub>2</sub>, ... ''A''<sub>''n''</sub>) is written as follows: :<math>G_1, G_2, \ldots, G_m\ g_{f_1({A_1}'), f_2({A_2}'), \ldots, f_k({A_k}')}\ (r)</math> where each ''A''<sub>''j''</sub>', 1 β€ ''j'' β€ ''k'', is one of the original attributes ''A''<sub>''i''</sub>, 1 β€ ''i'' β€ ''n''. The attributes preceding the ''g'' are grouping attributes, which function like a "group by" clause in SQL. Then there are an arbitrary number of aggregation functions applied to individual attributes. The operation is applied to an arbitrary relation ''r''. The grouping attributes are optional, and if they are not supplied, the aggregation functions are applied across the entire relation to which the operation is applied. Let's assume that we have a table named {{mono|Account}} with three columns, namely {{mono|Account_Number, Branch_Name}} and {{mono|Balance}}. We wish to find the maximum balance of each branch. This is accomplished by <sub>{{mono|Branch_Name}}</sub>''G''<sub>Max({{mono|Balance}})</sub>({{mono|Account}}). To find the highest balance of all accounts regardless of branch, we could simply write ''G''<sub>Max({{mono|Balance}})</sub>({{mono|Account}}). Grouping is often written as <sub>{{mono|Branch_Name}}</sub>''Ι£''<sub>Max({{mono|Balance}})</sub>({{mono|Account}}) instead.<ref name="Garcia-MolinaUllman2009" /> === Transitive closure === Although relational algebra seems powerful enough for most practical purposes, there are some simple and natural operators on [[relation (database)|relation]]s that cannot be expressed by relational algebra. One of them is the [[transitive closure]] of a binary relation. Given a domain ''D'', let binary relation ''R'' be a subset of ''D''Γ''D''. The transitive closure ''R<sup>+</sup>'' of ''R'' is the smallest subset of ''D''Γ''D'' that contains ''R'' and satisfies the following condition: :<math>\forall x \forall y \forall z \left( (x,y) \in R^+ \wedge (y,z) \in R^+ \Rightarrow (x,z) \in R^+ \right)</math> It can be proved using the fact that there is no relational algebra expression ''E''(''R'') taking ''R'' as a variable argument that produces ''R''<sup>+</sup>.<ref>{{cite journal|title=Universality of data retrieval languages|journal=Proceedings of the 6th ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages|year=1979|first=Alfred V.|last=Aho|author2=Jeffrey D. Ullman |pages=110β119|doi=10.1145/567752.567763|s2cid=3242505 |doi-access=free}}</ref> SQL however officially supports such [[Hierarchical and recursive queries in SQL|fixpoint queries]] since 1999, and it had vendor-specific extensions in this direction well before that. == Use of algebraic properties for query optimization == {{unreferenced section|date=June 2013}} {{multiple image | width = 140 | image1 = Triangle-query-join-query-plan-r-st.svg | alt1 = A query plan for the triangle query R(A, B) β S(B, C) β T(A, C) that uses binary joins. It joins S and T first, then joins the result with R. | image2 = Triangle-query-join-query-plan-rs-t.svg | alt2 = A query plan for the triangle query R(A, B) β S(B, C) β T(A, C) that uses binary joins. It joins R and S first, then joins the result with T. | footer = Two possible [[query plan]]s for the {{dfni|triangle query}} {{math|R(A, B) β S(B, C) β T(A, C)}}; the first joins {{mvar|S}} and {{mvar|T}} first and joins the result with {{mvar|R}}, the second joins {{mvar|R}} and {{mvar|S}} first and joins the result with {{mvar|T}} }} [[Relational database management systems]] often include a [[query optimizer]] which attempts to determine the most efficient way to execute a given query. Query optimizers enumerate possible [[query plan]]s, estimate their cost, and pick the plan with the lowest estimated cost. If queries are represented by operators from relational algebra, the query optimizer can enumerate possible query plans by rewriting the initial query using the algebraic properties of these operators. [[relational query|Queries]] can be represented as a [[tree (data structure)|tree]], where * the internal nodes are operators, * leaves are [[relation (database)|relation]]s, * subtrees are subexpressions. The primary goal of the query optimizer is to transform [[Binary expression tree|expression trees]] into equivalent expression trees, where the average size of the relations yielded by subexpressions in the tree is smaller than it was before the [[query optimization|optimization]]. The secondary goal is to try to form common subexpressions within a single query, or if there is more than one query being evaluated at the same time, in all of those queries. The rationale behind the second goal is that it is enough to compute common subexpressions once, and the results can be used in all queries that contain that subexpression. Here are a set of rules that can be used in such transformations. === Selection === Rules about selection operators play the most important role in query optimization. Selection is an operator that very effectively decreases the number of rows in its operand, so if the selections in an expression tree are moved towards the leaves, the internal [[relation (database)|relation]]s (yielded by subexpressions) will likely shrink. ==== Basic selection properties ==== Selection is [[idempotent]] (multiple applications of the same selection have no additional effect beyond the first one), and [[commutative]] (the order selections are applied in has no effect on the eventual result). #<math>\sigma_{A}(R)=\sigma_{A}\sigma_{A}(R)\,\!</math> #<math>\sigma_{A}\sigma_{B}(R)=\sigma_{B}\sigma_{A}(R)\,\!</math> ==== Breaking up selections with complex conditions ==== A selection whose condition is a [[Logical conjunction|conjunction]] of simpler conditions is equivalent to a sequence of selections with those same individual conditions, and selection whose condition is a [[Logical disjunction|disjunction]] is equivalent to a union of selections. These identities can be used to merge selections so that fewer selections need to be evaluated, or to split them so that the component selections may be moved or optimized separately. #<math>\sigma_{A \land B}(R)=\sigma_{A}(\sigma_{B}(R))=\sigma_{B}(\sigma_{A}(R))</math> #<math>\sigma_{A \lor B}(R)=\sigma_{A}(R)\cup\sigma_{B}(R)</math> ==== Selection and cross product ==== Cross product is the costliest operator to evaluate. If the input [[relation (database)|relation]]s have ''N'' and ''M'' rows, the result will contain <math>NM</math> rows. Therefore, it is important to decrease the size of both operands before applying the cross product operator. This can be effectively done if the cross product is followed by a selection operator, e.g. <math>\sigma_{A}(R \times P)</math>. Considering the definition of join, this is the most likely case. If the cross product is not followed by a selection operator, we can try to push down a selection from higher levels of the expression tree using the other selection rules. In the above case the condition ''A'' is broken up in to conditions ''B'', ''C'' and ''D'' using the split rules about complex selection conditions, so that <math>A = B \wedge C \wedge D</math> and ''B'' contains attributes only from ''R'', ''C'' contains attributes only from ''P'', and ''D'' contains the part of ''A'' that contains attributes from both ''R'' and ''P''. Note, that ''B'', ''C'' or ''D'' are possibly empty. Then the following holds: :<math>\sigma_{A}(R \times P) = \sigma_{B \wedge C \wedge D}(R \times P) = \sigma_{D}(\sigma_{B}(R) \times \sigma_{C}(P))</math> ==== Selection and set operators ==== Selection is [[distributive property|distributive]] over the set difference, intersection, and union operators. The following three rules are used to push selection below set operations in the expression tree. For the set difference and the intersection operators, it is possible to apply the selection operator to just one of the operands following the transformation. This can be beneficial where one of the operands is small, and the overhead of evaluating the selection operator outweighs the benefits of using a smaller [[relation (database)|relation]] as an operand. #<math>\sigma_{A}(R\setminus P)=\sigma_{A}(R)\setminus \sigma_{A}(P) =\sigma_{A}(R)\setminus P</math> #<math>\sigma_{A}(R\cup P)=\sigma_{A}(R)\cup\sigma_{A}(P)</math> #<math>\sigma_{A}(R\cap P)=\sigma_{A}(R)\cap\sigma_{A}(P)=\sigma_{A}(R)\cap P=R\cap \sigma_{A}(P)</math> ==== Selection and projection ==== Selection commutes with projection if and only if the fields referenced in the selection condition are a subset of the fields in the projection. Performing selection before projection may be useful if the operand is a cross product or join. In other cases, if the selection condition is relatively expensive to compute, moving selection outside the projection may reduce the number of tuples which must be tested (since projection may produce fewer tuples due to the elimination of duplicates resulting from omitted fields). :<math>\pi_{a_1, \ldots ,a_n}(\sigma_A( R )) = \sigma_A(\pi_{a_1, \ldots,a_n}( R ))\text{ where fields in }A \subseteq \{a_1,\ldots,a_n\}</math> === Projection === ==== Basic projection properties ==== Projection is idempotent, so that a series of (valid) projections is equivalent to the outermost projection. :<math>\pi_{a_1, \ldots , a_n}(\pi_{b_1,\ldots , b_m}(R)) = \pi_{a_1, \ldots , a_n}(R)\text{ where }\{a_1, \ldots , a_n\} \subseteq \{b_1, \ldots , b_m\}</math> ==== Projection and set operators ==== Projection is [[distributive property|distributive]] over set union. :<math>\pi_{a_1, \ldots, a_n}(R \cup P) = \pi_{a_1, \ldots, a_n}(R) \cup \pi_{a_1, \ldots, a_n}(P). \, </math> Projection does not distribute over intersection and set difference. Counterexamples are given by: :<math>\pi_A(\{ \langle A=a, B=b \rangle \} \cap \{ \langle A=a, B=b' \rangle \}) = \emptyset</math> :<math>\pi_A(\{ \langle A=a, B=b \rangle \}) \cap \pi_A(\{ \langle A=a, B=b' \rangle \}) = \{ \langle A=a \rangle \}</math> and :<math>\pi_A(\{ \langle A=a, B=b \rangle \} \setminus \{ \langle A=a, B=b' \rangle \}) = \{ \langle A=a\rangle \}</math> :<math>\pi_A(\{ \langle A=a, B=b \rangle \}) \setminus \pi_A(\{ \langle A=a, B=b' \rangle \}) = \emptyset\,,</math> where ''b'' is assumed to be distinct from {{var|b'}}. === Rename === ==== Basic rename properties ==== Successive renames of a variable can be collapsed into a single rename. Rename operations which have no variables in common can be arbitrarily reordered with respect to one another, which can be exploited to make successive renames adjacent so that they can be collapsed. #<math>\rho_{a / b}(\rho_{b / c}(R)) = \rho_{a / c}(R)\,\!</math> #<math>\rho_{a / b}(\rho_{c / d}(R)) = \rho_{c / d}(\rho_{a / b}(R))\,\!</math> ==== Rename and set operators ==== Rename is distributive over set difference, union, and intersection. #<math>\rho_{a / b}(R \setminus P) = \rho_{a / b}(R) \setminus \rho_{a / b}(P)</math> #<math>\rho_{a / b}(R \cup P) = \rho_{a / b}(R) \cup \rho_{a / b}(P)</math> #<math>\rho_{a / b}(R \cap P) = \rho_{a / b}(R) \cap \rho_{a / b}(P)</math> === Product and union === Cartesian product is distributive over union. #<math>(A \times B) \cup (A \times C) = A \times (B \cup C)</math> == Implementations == The first query language to be based on Codd's algebra was Alpha, developed by Dr. Codd himself. Subsequently, [[ISBL]] was created, and this pioneering work has been acclaimed by many authorities<ref>{{cite web |title = Edgar F. Codd - A.M. Turing Award Laureate |url = https://amturing.acm.org/award_winners/codd_1000892.cfm |author = C. J. Date |website = amturing.acm.org |access-date = 2020-12-27 }}</ref> as having shown the way to make Codd's idea into a useful language. [[Business System 12]] was a short-lived industry-strength relational DBMS that followed the ISBL example. In 1998 [[Christopher J. Date|Chris Date]] and [[Hugh Darwen]] proposed a language called '''Tutorial D''' intended for use in teaching relational database theory, and its query language also draws on ISBL's ideas.<ref>{{cite web |title = Databases, Types, and the Relational model: The Third Manifesto |author = C. J. Date and Hugh Darwen |url = https://www.dcs.warwick.ac.uk/~hugh/TTM/DTATRM.pdf |access-date = 2024-07-04}}</ref> Rel is an implementation of '''Tutorial D'''. Bmg is an implementation of relational algebra in Ruby which closely follows the principles of '''Tutorial D''' and ''The Third Manifesto''.<ref>{{cite web |title = Bmg documentation |url = https://www.relational-algebra.dev/ |access-date = 2024-07-04}}</ref> Even the query language of [[SQL]] is loosely based on a relational algebra, though the operands in SQL ([[table (database)|table]]s) are not exactly [[relation (database)|relation]]s and several useful theorems about the relational algebra do not hold in the SQL counterpart (arguably to the detriment of optimisers and/or users). The SQL table model is a bag ([[multiset]]), rather than a set. For example, the expression <math>(R \cup S) \setminus T = (R \setminus T) \cup (S \setminus T)</math> is a theorem for relational algebra on sets, but not for relational algebra on bags.<ref name="Garcia-MolinaUllman2009">{{cite book |author1 = [[Hector Garcia-Molina]] |author2 = [[Jeffrey Ullman|Jeffrey D. Ullman]] |author3 = [[Jennifer Widom]] |title = Database systems: the complete book |year = 2009 |publisher = Pearson Prentice Hall |isbn = 978-0-13-187325-4 |edition = 2nd }}</ref> == See also == {{div col|colwidth=25em}} * [[Cartesian product]] * [[Codd's theorem]] * [[D4 (programming language)]] (an implementation of D) * [[Data modeling]] * [[Database]] * [[Datalog]] * [[Logic of relatives]] * [[Object-role modeling]] * [[Projection (mathematics)]] * [[Projection (relational algebra)]] * [[Projection (set theory)]] * [[Relation (mathematics)|Relation]] * [[Relation (database)]] * [[Relation algebra]] * [[Relation composition]] * [[Relation construction]] * [[Relational calculus]] * [[Relational database]] * [[Relational model]] * [[SQL]] * [[Theory of relations]] * [[Triadic relation]] * [[Tuple relational calculus]] {{div col end}} ==Notes== {{notelist}} == References == {{reflist}} == Further reading == * {{Cite journal | last1 = ImieliΕski | first1 = T. | author-link= Tomasz ImieliΕski | last2 = Lipski | first2 = W. | doi = 10.1016/0022-0000(84)90077-1 | title = The relational model of data and cylindric algebras | journal = [[Journal of Computer and System Sciences]] | volume = 28 | pages = 80β102| year = 1984 | doi-access = free }} (For relationship with [[cylindric algebra]]s). == External links == {{external links|date=January 2017}} * [https://web.archive.org/web/20220330063834/https://www.slinfo.una.ac.cr/rat/rat.html RAT Relational Algebra Translator] Free software to convert relational algebra to SQL * [http://www.databaselecture.com/processing.html Lecture Videos: Relational Algebra Processing] - An introduction to how database systems process relational algebra * [http://www.databasteknik.se/webbkursen/relalg-lecture/index.html Lecture Notes: Relational Algebra] β A quick tutorial to adapt SQL queries into relational algebra * [https://ltworf.codeberg.page/relational/ Relational β A graphic implementation of the relational algebra] * [https://graal.ens-lyon.fr/~yrobert/henri3/ioannidis96query.pdf Query Optimization] This paper is an introduction into the use of the relational algebra in optimizing queries, and includes numerous citations for more in-depth study. <!-- (Page deleted; Closest alternatives: [https://web.stanford.edu/class/cs345d-01/rl/chaudhuri98.pdf Standford Query Optimization 2], [https://web.stanford.edu/class/cs345d-01/rl/chaudhuri98.pdf Microsoft research Query Optimization in relational systems], [http://infolab.stanford.edu/lore/pubs/qo.pdf Stanford paper: Query Optimization]) --> * [https://www.cse.fau.edu/~marty/index.html#RADownload Relational Algebra System for Oracle and Microsoft SQL Server] * [https://centaurialpha.github.io/pireal/index.html Pireal β An experimental educational tool for working with Relational Algebra] * [http://des.sourceforge.net DES β An educational tool for working with Relational Algebra and other formal languages] * [https://dbis-uibk.github.io/relax/ RelaX - Relational Algebra Calculator] (open-source software available as an online service without registration) * [https://users.cs.duke.edu/~junyang/ra2/ RA: A Relational Algebra Interpreter] * [http://mlwiki.org/index.php/Translating_SQL_to_Relational_Algebra Translating SQL to Relational Algebra] {{Databases}} [[Category:Relational algebra| ]] [[Category:Relational model]] [[Category:Database management systems]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:And
(
edit
)
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite conference
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Col-begin
(
edit
)
Template:Col-break
(
edit
)
Template:Col-end
(
edit
)
Template:Databases
(
edit
)
Template:Distinguish
(
edit
)
Template:Div col
(
edit
)
Template:Div col end
(
edit
)
Template:Efn
(
edit
)
Template:External links
(
edit
)
Template:Main
(
edit
)
Template:Math
(
edit
)
Template:Mono
(
edit
)
Template:Multiple image
(
edit
)
Template:Not
(
edit
)
Template:Notelist
(
edit
)
Template:NumBlk
(
edit
)
Template:Or-
(
edit
)
Template:Redirect
(
edit
)
Template:Reflist
(
edit
)
Template:Rp
(
edit
)
Template:See also
(
edit
)
Template:Short description
(
edit
)
Template:Split section
(
edit
)
Template:Unreferenced section
(
edit
)
Template:Var
(
edit
)
Template:Ξ¦
(
edit
)