2

For my personal project I need to store 2D shapes in a Postgres database. For example Circle, Pentagon, Rectangle and so on. At first I've done it like so: all shapes are inherited from an abstract class called Shapes, which has some methods that I need each object to perform on itself, for example (I'm using java with Spring data):

for(Shape shape : shapes){
    shape.getArea();
}

This is good in code, but I don't know a good way to store this in a database. Every shape has some parameters that are different from others (radius for circle, height and length for rectangle etc.) so it looks like I need many tables for each geometry type. But how to reference each shape from another table then?

Right now I try to solve this with a single class called Geometry. It has a type field and a set of parameters linked to it Circle for example will have one record in table Geometry and one record in table Parameters. This class also has all the methods needed for each available shape, like this:

getArea(){
    switch(type){
        case circle: ....
        case pentagon: ...
    }
}

But I'm wondering if there are more elegant ways to solve this?

1

2 Answers 2

1

That depends on if you just want to store the shapes, or perform queries on their properties.

If you just want to store them, the simplest way is to serialize them and store the serialized data, along with a shapeid field to let you know what kind of shape you've got. Each subclass could handle its own serialization. Very similar to storing images in a database.

If you want to perform queries on the properties of a given shape, you have to expose those properties as columns on a table, or use PostgreSQL's geometric types (as Patrick Mevzek mentioned). However, using types from a given database engine is not very portable.

3
  • I want just to persist objects. In case the server goes down.
    – Zmur
    Commented Jan 19, 2018 at 17:28
  • @Zmur, then you could simply obtain a JSON representation of the whole drawing sheet (or, for that matter, a SVG representation) and save it in the database. A single table: drawing. select id, data from drawing where user = .... Commented Jan 19, 2018 at 21:17
  • @turdus-merula This may actually work for me. Thank you!
    – Zmur
    Commented Jan 20, 2018 at 7:50
1

To maintain a complex geometric programme with all kind of shapes, you'd better go for polymorphism, and classes inheriting from Shape. This will make code more understandable and more maintainable (i.e. it's easier to add a new shape with polymorphism rather than with long switches).

Now for the persistance in a relational database, you have several alternatives that are very well described in Martin Fowler's book "Pattern of Enterprise Application Architecture":

  • As there are not so much parameters for a shape, you could go fo single table inheritance: you'd have a single table holding all the data, a little bit like with your geometry class.
  • If your shapes would be very complex, with lots of different data, you could go for class table inheritance: every class would have its own table (including Shape if it would have some kind of common data) .
  • Between both you'd have a concrete table inheritance, where every most derived class would have its own table with all its data (so the Squares and the Circles, but not Shape itself.

So the trick is to decouple somewhat the objects living in memory and the way they are stored in the database.

3
  • But I will get a lot of fields with null values that way. One for each shape in each object that references it no?
    – Zmur
    Commented Jan 19, 2018 at 17:31
  • Using the first option (single table inheritance), is it normal practice to have a column the specifies the Object type? Or should we just use the existence of certain columns to determine the type? Which is best practice if any?
    – theyuv
    Commented Mar 28, 2019 at 11:35
  • @theyuv yes, it is normal practice that an information about type is used. Eventually, the type could be derived from fields of the base class (so always available), but this is more risky in view of future evolution (because there is a hidden coupling). Finally deducing the type form the variable columns is imho not recommended.
    – Christophe
    Commented Mar 28, 2019 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.