Hacker News new | ask | show | jobs
by weavejester 2615 days ago
I'm not talking about building a database; I'm talking about using a relational model for data.

Like most general-purpose programming languages, Clojure has a hierarchical data model. We have a number of collection types, and we can put any collection into any other collection.

A relational model takes a fundamentally different approach. Relational data is represented not by nesting collections, but by a flat set of tuples. Efficiency is achieved through indexing, not by rearranging collections.

There's some interesting research around on using the relational model outside of a database, but that's not a design goal of Clojure.

1 comments

My method can also generate a "derived index" based on the "primary key hash index",it's Higher performance, not by rearranging collections.

```clojure

(def table01 {:t1-pk1 {:pk :t1-pk1

                       :name    "t1-r1"

                       :manager :m1}

              :t1-pk2 {:pk      :t1-pk2

                       :name    "t1-r2"

                       :manager :m2}

              :t1-pk3 {:pk      :t1-pk3

                       :name    "t1-r3"

                       :manager :m3}

              :t1-pk4 {:pk      :t1-pk4

                       :name    "t1-r4"

                       :manager :m2}})
(def t1-manager-index {:m1 #{:t1-pk1}

                       :m2 #{:t1-pk2 

                             :t1-pk4}

                       :m3 #{:t1-pk3}})      
(->> :m2

     t1-manager-index

     (select-keys table01 ,)) 
 
; =>

; {:t1-pk2 {:pk :t1-pk2, :name "t1-r2", :manager :m2},

; :t1-pk4 {:pk :t1-pk4, :name "t1-r4", :manager :m2}}

(->> [:m2 :m3]

     (select-keys t1-manager-index ,)

     vals

     (apply clojure.set/union ,)

     (select-keys table01 ,)) 
 
; =>

; {:t1-pk2 {:pk :t1-pk2, :name "t1-r2", :manager :m2},

; :t1-pk4 {:pk :t1-pk4, :name "t1-r4", :manager :m2},

; :t1-pk3 {:pk :t1-pk3, :name "t1-r3", :manager :m3}}

```

Your point of view is mainly to emphasize that Clojure is a multi-paradigm, general-purpose functional programming language.

The postgresql development team is also this view, so postgresql is not only RMDB (relational modeling), but also supports OO and json (NoSQL). But postgresql default data modeling is relational modeling

My point of view is mainly to emphasize the best practices of data modeling and programming.

Both views are correct and can exist in parallel.

"Your point of view is mainly to emphasize that Clojure is a multi-paradigm, general-purpose functional programming language."

No, that's not my point at all. I'm saying that Clojure's core library and data structures are built around a hierarchical data model and not a relational one.

If you want to model your data as a relation, then you need to build the tools and structures for it. Look at your code, then consider how it would look in a language designed around relational algebra:

    (def table01
      #rel [{name "t1-r1", manager :m1}
            {name "t1-r2", manager :m2}
            {name "t1-r3", manager :m3}
            {name "t1-r4", manager :m2}])

    (select table01 (= manager :m2))

    ; => #rel [{name "t1-r2", manager :m2}
    ;          {name "t1-r4", manager :m2}] 

    (select table01 (or (= manager :m2) (= manager :m3)))

    ; => #rel [{name "t1-r2", manager :m2}
    ;          {name "t1-r3", manager :m3}
    ;          {name "t1-r4", manager :m2] 
An indexed selection against a relation would just be a single function or macro. We wouldn't need to mess around with select-keys and set union to achieve such a simple operation, as you needed to do in your code. It would be built into the core library or the language.

I want to emphasize that I'm not saying you shouldn't model data the way you are. There are plenty of advantages to it. But the more you go down the relational rabbit hole, the less suitable clojure.core is to handle it.

Clojure is about data modelling and processing, but it isn't based on a relational model, as you suggest:

"Clojure is a functional programming language based on relational database theory"

Clojure is a functional programming language, but it's not based on relational database theory.

If Clojure is the sea, programming is to sail on the sea, I use the relational model as a lighthouse and route, as a reference model for simple programming, because the relationship theory is simple and scientific..

I had implemented a DataFrame with hash-map, which implements relational operations. A relational operation is just a function. The advantage of hash-map is that key-chain can be used as a pointer, and processing data elements is simple and efficient. Therefore, DataFrame has advantages of RMDB and NoSQL.

A strict relational model will lose the flexibility of data element operations.