Reputation: 91
I'm thinking about how to represent functional dependencies in as a data structure.
A functional depdendency (of a relation schema of a database) maps a set of attributes to a set of attributes. E.g. in {A, B} -> {C, D} the attributes C and D are functional dependent on A and B.
I can think of four possible cases here:
My first approach was a simple two member class:
class attribute
{
string name;
set<attribute*> dependent_on;
}
This would work with functional dependencies like (1) but not with (2) - (4) - I think. I could decompose (3), indeed, but I see no way to represent (2) and (4) with such a class.
I have to keep the information that C and D are functional dependent on A and B, so I would have to make a class like attributegroup
where a set of attributes is mapped to a set of attributes. E.g.:
class attributegroup
{
set<attribute*> members;
set<attribute*> dependent_on;
}
So actually I could represent a single attribute simply as an attributegroup
with only one member. But I do not think that this is the best way to do this.
Any help/thoughts appreciated :)
Upvotes: 1
Views: 980
Reputation:
I would not store dependencies in an attribute:
include <iostream>
#include <map>
#include <vector>
struct Attribute;
typedef std::vector<Attribute> Attributes;
struct Attribute {
char name;
operator Attributes () const { return Attributes{ 1, *this }; }
};
inline bool operator < (const Attribute& a, const Attribute& b) {
return a.name < b.name;
}
inline bool operator < (const Attributes& a, const Attributes& b) {
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end());
}
inline std::ostream& operator << (std::ostream& stream, const Attributes& attributes) {
for(const auto& a: attributes) {
std::cout << a.name;
}
return stream;
}
typedef std::multimap<Attributes, Attributes> AttributeDependencies;
typedef AttributeDependencies::value_type AttributeDependency;
int main(int argc, const char* argv[]) {
Attribute a {'A'};
Attribute b {'B'};
Attribute c {'C'};
Attribute d {'D'};
AttributeDependencies dpendencies;
dpendencies.insert(AttributeDependency(a, b));
dpendencies.insert(AttributeDependency(Attributes{a, b}, c));
dpendencies.insert(AttributeDependency(a, Attributes{b, c}));
dpendencies.insert(AttributeDependency(Attributes{a, b}, Attributes{c, d}));
for(const auto& d: dpendencies) {
std::cout << '{' << d.first << "} -> {" << d.second << "}\n";
}
return 0;
}
Note: A std::map might be the right container, but std::multimap fits the example data.
Upvotes: 1