[HN Gopher] Stored Procedures as a Back End ___________________________________________________________________ Stored Procedures as a Back End Author : steve-chavez Score : 106 points Date : 2020-12-03 16:13 UTC (6 hours ago) (HTM) web link (gnuhost.medium.com) (TXT) w3m dump (gnuhost.medium.com) | nwsm wrote: | Nice work; PostgREST seems neat. However, the aim of this stack | is simplicity, but it is incompatible with serverless products, | which I now vastly prefer for ease of use and lower effort- | traits I would consider part of "simplicity". | | But I'm sure there is a valid argument contrasting simplicity | with a managed nature of a tech stack, not to mention a cost | comparison. | capableweb wrote: | > However, the aim of this stack is simplicity, but it is | incompatible with serverless products, which I now vastly | prefer for ease of use and lower effort- traits | | The issue with this statement is that you're comparing things | that works on different layers. PostgREST is for someone to | host the database without any backend, serverless as you | describe it is just a SaaS service you use. If there was a SaaS | that exposed PostgREST as a service, it'll be a similar | experience. | | So unless you're comparing running a serverless platform | yourself with running PostgREST yourself (which would be pretty | obvious which one is the easiest), I feel like you missed with | your argument here. | nwsm wrote: | I'm talking about the stack as a whole, which happens to be | built on PostgREST. | | The OP's goal was to simplify their stack, which they did do. | However, they cannot run this stack without managing a | database, as the database and REST API are run in the same | container. My point is that another way to lower a project's | required effort is to offload database management. | | Sure, OP now only has two layers in the stack instead of | three. But now they are locked into managing the database | entirely, including updates, backups, and scaling. | steve-chavez wrote: | If you like serverless, Supabase[1] will handle all the | PostgreSQL and PostgREST management for you :) | | [1]: https://supabase.io/beta | 8note wrote: | How do you handle decoupling your API model from your database | model? | ellimilial wrote: | This won't answer this question in full but perhaps some part | of it. | | Projects like PostgREST (and PostGraphile) use schema | introspection to generate the API. When the schema changes it's | automatically reflected in the API. Sure one has to keep the | changes synced on the frontend but the premise is you don't | want to decouple. | loldot_ wrote: | What I've found being the problem with this approach is that sql | does not lend itself very well to composability. Sure, you can | make functions, views and stored procedures and compose them. But | when you start actually composing queries of these parts the | could lead to different execution plans having wildly different | performance characteristics. | | Also tooling around SQL, i.e. refactoring tools and debuggers, is | not great - if even available at all. | corytheboyd wrote: | How does this work with database replication? Does all | "application logic" have to execute on the master database? | kemiller2002 wrote: | Not necessarily. You can make it so that cross replicated | databases can function independently and then sync the data | together. This of course assumes that you don't have something | like an ordering system and you absolutely need to make sure | that you don't sell more than your inventory. | corytheboyd wrote: | That makes sense, yeah. I admittedly haven't studied the | pieces of the stack, but maybe something like PostgREST | allows routing certain requests to master vs any replica, | where you could make the atomic transactions needed for | inventory based updates. | | This is all completely outside the realm of things I'll ever | get into haha. IMO so what if the current app/db server | boundary is "slow" or "adds too many moving parts" I already | spent my entire career learning it, there is value in that to | me. | throwaway_pdp09 wrote: | > Also typical database uses 96% of the time for logging, locking | etc. and 4% percent for actual data operations | | That's a strange claim, in my work it's always been 100% data | ops. | | > "Letting people connect directly to the database is a madness" | -- yes it is. | | why? | | > Killing database by multiple connections from single network | port is simply impossible in real life scenario. You will long | run out of free ports | | Depends entirely on the workload. And it's very possible. All too | entirely so. | taffer wrote: | > why? while true: select count(*) from | huge_table | | thats why. | _benj wrote: | In my experience I actually got A LOT more from this approach | using postgraphile/Hasura in front of my DB and later moved to | dosco/super-graph in order to add custom functionality that was | kind of a pain to do on the DB. | | I really liked the mixed approach of have the DB do everything | that it can and have a light backend that can handle http | requests, api callbacks, image manipulation and whatever else. | BenjieGillam wrote: | Out of interest (as the PostGraphile maintainer) did you look | into https://www.graphile.org/postgraphile/make-extend-schema- | plu... for extending the PostGraphile schema to do whatever you | need, or were you specifically looking to implement the | extensions in Go? | lflux wrote: | At a previous job I was at 2007-2014, we were doing classified | ads[1] we had a lot of logic in stored procedures in our Postgres | database written in pl/pgsql. It made sense at the time, but | after a while these got really unwieldy and deploying things got | tricky, since you we needed to update both appserver code and | database stored procs at the same time. There also wasn't a great | way to update stored procs at the time - we built this into an | RPM that just ran a postinstall script to do an atomic swap. | | I wouldn't build this into the database were I to build it today. | | [1] blocket.se/leboncoin.fr/segundamano.(es,mx) | FlyingSnake wrote: | Using a database as a backend comes up time and again and | developers are sharpely divided over this concept. I feel that | developers who started their careers before the advent of NoSQL | DBs/MEAN stack/etc had to go through the rigor of fine tuning | their SQL queries and witness the powers (and quirks) of a | performant SQL DB. These devs are usually a fan of using DB-as-a- | backend. Personally, I am a big fan of PostgREST and I apply it | whenever I find a use case that suits it. I find it quite | pragmatic and it just shines when it plays to it's strength. | Pragmatic developers should took a pragmatic look at such | approaches and try to use the powerhouse that are SQL DB engines. | | Shameless plug: I've written an article to showcase it's | philosophy and how easy it is to get started with PostgREST. | | [^1]: | https://samkhawase.com/blog/postgrest/postgrest_introduction... | pjmlp wrote: | I am on the stored procedure side, and see no value in wasting | network bandwidth and client resources for what the RDMS should | do itself. | Raidion wrote: | If I make the change in code, I can roll it out, test it in prod, | and then slowly migrate traffic over in very standard and well | defined ways. | | If I deploy to the database and something goes wrong, I need to | really trust my rollback scripts. If the rollback scripts go | haywire, you're in a tough spot. If that happens to code, you can | literally just move all the traffic to the same thing that was | working before, you don't quite have that luxury with the | database. | | You can have a bunch of servers, you really only can have one | database. This means the database should be very sensitive to | changes because it's a single point of failure. I don't like | modifying or changing single points of failure without very good | and well tested reasons. | | Could you version your procs and have the new version of the code | call the new procs? Sure, but now you have to manage deployment | of both a service, and the database, and have to handle rollover | and/or A/B for both. If my logic is in there service, I only have | to worry about rolling back the service. | | Database logic saves you a little bit of pain in development for | a ton of resilience and maintenance costs, and it's not worth it | in the long run IMO. Maybe it's because the tooling isn't that | mature, but until I can A/B test an atomic database, this doesn't | work for a lot of applications. | ComputerGuru wrote: | I fully agree and treat my databases the same way. However, | there's no reason a stored procedure couldn't be treated the | same way with a random weight determining which version of a | stored procedure is run. | | But I still wouldn't. | chaps wrote: | Not sure I follow in the context of the post. The post is about | a database that can be wiped and effectively recreated from | scratch. There wouldn't really be a need for rollback scripts | when you can just rerun the entire workflow from scratch. Even | easier if you have a hot/warm/cold setup. | | In this sort of setup, changing a db function isn't unlike | making a change to db-interfacing code in that it's not | changing the underlying data, just the interface to it. | | I've built similar systems that instead of making changes to db | functions, changes are made to materialized views. The | underlying data doesn't change, but its presentation does. No | huge need for rollbacks. It works really well! | Roboprog wrote: | Presumably you can revert to a previous tag/label in source | control and reload the previous procs/funcs to roll back | versions. | | The apps I have been working on are monoliths which run at | about 2% CPU on the server, so there is no A/B comparison runs | in production (e.g. on January 1, some law goes into effect and | you WILL implement it). I would happily see ORM usage curb | stomped. | alphanumeric0 wrote: | I personally would not make this choice for new projects. I only | use technology that is appropriate for the domain I'm using it | in. Although, I am hoping this trend encourages better tooling | and more modernization of SQL. | | As others stated, my concerns are primarily that SQL lacks a lot | of general-purpose language features (modules, namespacing, | composability, no easy way to debug, etc.) which seem to be ideal | for writing applications. | | I would be interested to see a project written with PL/Python + | PL/SQL stored functions in Postgres. PL/Python functions would be | the interface between API calls and the database, and SQL would | do what it is currently designed to do: straight-forward data | manipulation. | Brentward wrote: | Not that this is an important part of the post, but in general | parsing the output of ls like the author does in the for loop is | a bad idea[1]. | | I think the one-liner would be better as for i in | [0-8]*/*.sql; do psql -U <user> -h localhost -d <dbname> -f $i ; | done | | or even better as something like find . -name | "*.sql" -exec psql -U <user> -h localhost -d <dbname> -f {} \; | | [1] http://mywiki.wooledge.org/ParsingLs | tacticaldev wrote: | I'm currently part of a team trying to UNDO this very concept. It | sounded great in the beginning, but after years of headaches and | wasted cash; we're building the backend in something else. I | wasn't part of the original team. Nor was I part of the decision | to migrate off of the system. I just know that for my employer, | it was a bad decision those many years ago... | pjmlp wrote: | Sure, because wasting network bandwith for going through | needless data on the client is such a clever idea. | sumtechguy wrote: | This takes a balance to get right. For some data yes drag it | over and keep it on the 'client'. But for other data just | join it out and let the SQL handle it. However, for some | reason SQL seems to scare a lot of people. So they end up | making lots of microservices/functions/methods that just drag | the data together and mash it together in a language they | understand. That comes at a cost of network bandwidth. | | I found that if you are 'happy' with the style of lots of | stored procs and data lifting on the server side you usually | have a decent source delivery system in place. If you do not | have that you will fight every step of the way changing the | schema and procs as this monolithic glob that no one dares to | touch. | gnat wrote: | Could you be more specific about the problems you're hoping to | fix/benefits you're hoping to gain by dragging the backend | logic out of the database? | jrochkind1 wrote: | Everything old is new again. This was a common way to write | client-server software in the pre-web world, clients talking | directly to a central rdbms. | | I guess the one true thing in software dev is the cycle/pendulum | keeps rotating/swinging. Often without people realizing it's | swinging back instead of brand new! | laudable-logic wrote: | Maybe sorta off-topic, but does anybody have any stories to tell | about successes/fails with the .NET CLR in MSSQL? | | I worked on a project that made moderate use of this. Worked | alright; biggest problem was convincing DBAs/IT to enable it. | | https://en.m.wikipedia.org/wiki/SQL_CLR | flerchin wrote: | Good luck debugging! Seriously. You can't attach a debugger to | your DB. | vsareto wrote: | DBs can have debuggers and breakpoints, but they do not come | anywhere close to something like Visual Studio debugging C# | code. | | Of course, many programming languages also do not have a | debugging quality-of-life compared to Visual Studio. | bsg75 wrote: | https://www.pgadmin.org/docs/pgadmin4/development/debugger.h... | | https://dbeaver.com/docs/wiki/PGDebugger/ | | https://www2.navicat.com/manual/online_manual/en/navicat/mac... | | https://www.cybertec-postgresql.com/en/debugging-pl-pgsql-ge... | | Other platforms have options as well: | | https://docs.microsoft.com/en-us/sql/ssms/scripting/transact... | pjmlp wrote: | I do it all the time on Oracle, SQL Server and Informix. | | Better I can even optimize to native code, and still debug | them. | throwaway_pdp09 wrote: | IME I've never needed one. You get a copy of prod and test | against that. SPs are typically short, even when they're long | their functionality tends to be well defined, it's never been a | problem for me. | | You certainly can and do add logging, this can be useful. | mdoms wrote: | I don't know what industry you are in or what kind of data | your users entrust in you, but "just get a copy of prod" is | not an idea that would EVER fly in any organisation I have | worked in. Developers do not get access to production | customers' financial records, medical data or PII, ever. | throwaway_pdp09 wrote: | Hands up, it's a fair point. I've worked with data sets | that are mainly large aggregates of public data so security | isn't an issue. It's the code that's carefully protected. | | One exception is having access to that data because I was | working ON the prod server. Read that again. It was deeply | uncomfortable to work like this. Very worrying every day. | throwaway201103 wrote: | In those cases you have a set of test data that you use for | development and testing. It's not like you can attach a | Visual Studio debugger to production either. | gnat wrote: | I'm very interested in this, as I come from the web world yet | find myself in a company that has a 30-year legacy of putting | business logic into the database. It served them really well, and | that they run quite lean in terms of hardware. But they're built | on Microsoft tech ($$$), and moving things to a traditional | database=datastore cloud architecture would require a substantial | change. Does anyone have resources they can point me to on the | wisdom or folly of keeping this logic-in-database approach? It | seems like the tradeoffs in the different approaches are all | about where the smarts are, and whether you can horizontally | scale those smarts. Does that sound accurate? | mattmanser wrote: | Honestly, I find SQL Server worth the $$$, it's certainly not | Oracle $$$$$$$$$ as far as I understand it. | taffer wrote: | > It seems like the tradeoffs in the different approaches are | all about where the smarts are, and whether you can | horizontally scale those smarts. Does that sound accurate? | | The real question is whether you are going to ship your code to | your data or your data to your code. | aszen wrote: | I'm very curious about this pattern, but does the tooling exist | to make this feasible across a team. One of the big problems with | SQL views is their lack of discoverability. The lack of tooling | also plagues SQL based systems, I would miss goto definition, | find all references and sensible autocompletion. I am curious why | no one has built suitable tooling around all this, because it is | a great idea for lot's of scenarios | jdmoreira wrote: | Oh I feel like it's 2007 again and I'm a Junior developer writing | a frontend in Delphi and the business logic in PL/SQL. Those were | the days. | mrits wrote: | I'm not old enough to remember the first one but I know at least | Oracle beat you to this idea in the early 90s. | milesvp wrote: | Oracle really pushed this idea too, because they knew that it | would mean more load in the database so you'd need a bigger box | with with more cpus. Oracle charged per tiered cpu so their | incentives were not aligned with the dev's. IMHO this is pretty | damning reason to generally avoid using the db for this reason. | It may be true that a db has lots of spare cycles to utilize | but so do your hot spare servers, and I'd hope that you're not | trying to wring performance out of those without thinking long | and hard as to what hot spare means. | | Source: migrated code from oracle to mysql to avoid insane | licensing fees once upon a time. Luckily we only had limited | stored procedures at the time, most of which I could ignore. | jandrewrogers wrote: | Back in the mid-90s, this was how many of the high-end web apps | were built, using Oracle. Despite its limitations, and Oracle | license fees (but back then you were paying for Sun servers | anyway), it worked surprisingly well and was a reasonable model | for many database-driven web applications. Some of these systems | were used for mission-critical global operations handling | enormous amounts of money and complex business. It had a lot of | advantages versus other web app stacks at the time (commonly a | mountain of Perl). | | Oracle was happy to sell database licenses but made zero effort | to develop this way of using the database as a first-class | capability. They were astonished that it even worked as well as | it did, they did not expect people to take it that far. | | For some types of applications, something along these lines is | likely still a very ergonomic way of writing web apps, if the | tooling was polished for this use case. | pjmlp wrote: | I can assure you that still is how many high-end web apps are | built today. | | Just delivered one last month with plenty of T-SQL code in it. | kemiller2002 wrote: | Not surprising. Databases are built to be really efficient, | and with enough hardware, they can forgive a lot. Mediocre | developers can produce a lot of "working" code if they stand | on the shoulders of giants. (Not saying you or your team was | mediocre, I'm just saying that I've seen really bad code run | a lot of business processes. At the end of the day, it worked | and the company made money.) | pjmlp wrote: | Just like I keep seeing plenty of mediocre teams doing for | loops over GB of downloaded data and pegging Webserver CPUs | for stuff that should have stayed on the DB. | | Usually that is one of the things I end up fixing when | asked for performance tips, other is getting rid of ORMs | and learn SQL. | kemiller2002 wrote: | Oh don't get me wrong, there is a time and a place for | everything. There are many things that should be in the | database, and there are a lot of people that avoid it | because they don't want to learn SQL. You can have really | good reasons and elegant code in SQL. I'm merely saying | when someone immediately says, "that's dumb, you | shouldn't do that," they aren't looking at the whole | picture possibly and it was the choice that got the | programming running which is important. | jacques_chester wrote: | I did a take-home exercise earlier this week. They | provided access to a database and said << do thing >>. | Implied was that I should << do thing >> with a program | rather than a query. | | One of my solutions used Golang. It pulled data, looped a | lot, then put results back. It took approximately 4 | minutes. | | I included a second solution, using SQL. It selected into | the results table with a little bit of CTE magic. It took | approximately 600ms. | bartread wrote: | Interesting, and I've seen and implemented similar | optimisations plenty of times. The right query in the | right place at the right time can make all the | difference. | | Did you hear back from them with a positive response? | jacques_chester wrote: | Not yet, but it's a small firm. I trust the people | involved and I don't mind giving them some time to go | over it. | NicoJuicy wrote: | ORM's aren't that slow, they are quick to develop. | | When you see a bottleneck, you could use 2 systems ( eg. | EF by default and Dapper when doing optimizations) | kemiller2002 wrote: | It should be noted too that the 90s was really a different | world back then. Processing capabilities, and development tools | were vastly different. | | There was just so much stuff that you had to manually build you | don't have to now. (There are other complexities that we get to | worry about now.) One thing I noticed back then is that putting | stuff in the database just made things easier. In some | instances, it really did act as like an amplifier for getting | work done. Need to sort data? The database has things in place | to do that and really efficiently too. I remember working with | people, and if they had to make things like a linked list or a | binary tree, they were lost (Yes, these were CS people too. We | can argue about their education, but yes, they did graduate | with a CS degree). There was nothing really like Stack Overflow | to ask for help. You were really on your own for a large | portion of it. Database code really took care of a lot of that | for you. (Truthfully, the companies I worked for used MSSQL | Server back then, so your results might have been different.) | throwaway201103 wrote: | Yeah nobody in the 1990s with a real CS degree didn't know | what a linked list or binary tree was. They just didn't want | to bother coding it and testing it, when the database was | there and being used anyway. | jandrewrogers wrote: | Another unusual usage for SQL databases (today!) is as a data | type server. SQL databases have a very rich set of data types | with rigorous specification and myriad operators, | conversions, etc for all the types, more so than just about | any other programming environment. If you need correct | support for a complex data type operation in a development | environment with weak or non-existent type support, you can | use a SQL runtime to do that computation for you over a local | client connection. | | I've used PostgreSQL this way a few times to great effect. | The connection is over local IPC and never touches storage, | so the operation throughput is quite high. | kevincox wrote: | The primary issue I have seen with stored procedures is how you | update them. I would be curious how they manage that. | | Generally when releasing new code you want to do a gradual | release so that a bad release is mitigated. It would be possible | by creating multiple functions during the migration and somehow | dispatching between them in PostgREST but I would be interested | to see what they do. | | The other obvious concern is scaling which was only briefly | mentioned. In general the database is the hardest component of a | stack to scale, and if you start doing it do more of the | computation you are just adding more load. Not to mention that | you may have trouble scaling CPU+RAM+Disk separately with them | all being on a single machine. | capableweb wrote: | > Generally when releasing new code you want to do a gradual | release so that a bad release is mitigated | | Make each stored procedure not depend on any other procedure. | If you change one procedure, make sure that every existing | procedure can work with both the current and the future | version. Once compatible, start upgrading procedures one by | one. Add in monitoring and automatic checking of the values | during deployment, and you have yourself a system that can | safely roll out changes slowly. | | I'm not advising anyone to do this, it sounds horribly | inefficient to me, but it's probably possible with the right | tooling. | taffer wrote: | > The primary issue I have seen with stored procedures is how | you update them. I would be curious how they manage that. | | 1. You put your stored procedures in git. | | 2. You write tests for your stored procedures and have them run | as part of your CI. | | 3. You put your stored procedures in separate schema(s) and | deploy them by dropping and recreating the schema(s). You never | log into the server and change things by hand. | mattmanser wrote: | Wouldn't that lose all the cached query plans every deploy? | Could be wrong, bit rusty on that stuff now, been a while | since I worked on something where we had to worry about that. | jandrewrogers wrote: | Many scaling problems in databases are _because_ the | computation is not done in the database. Outside of exotic | cases, good database engines are rarely computation-bound in a | competently designed system. By pushing computation outside of | the database, it tends to increase the consumption of database | resources that actually are bottlenecks, typically effective | bandwidth (both memory and I /O). | | As a heuristic, moving computation to the data is almost always | much more scalable and performant than moving the data to the | computation. The root cause of most scalability issues is | excessive and unnecessary data motion. | tuatoru wrote: | Profound comment. Should be top of mind whenever programmers | think they need a cache. | | We've just seen a lower-level example of this principle in | action, with Apple's M1 processor and its Unified Memory | Architecture. | mattmanser wrote: | That's not been my experience at all. Quite the opposite. | | I actually can't remember a single time in 15 years where | I've ever seen that. Maybe it's happened, but I don't | remember, but I can easily recount tons of poorly performing | SQL queries though. Sub-selects, too many joins, missing | indexes, dead-locks, missing foreign keys... | | I'm not saying it wouldn't cause a problem, I'm saying I've | never, ever seen production code where someone dumped tons of | data out and then processed it. | | I have seen people try and make extremely complex ORM calls | that were fixed by hand-coded SQL, but that's a different | problem. | marmaduke wrote: | I think read replicas scale easily, so if it's views and such | then there is no problem. If you have to compute stuff during | writes, then it's hard, but probably solved by normalizing the | data. | kemiller2002 wrote: | Really anything can be a good or a bad idea depending on the | problem domain and how it's implemented. He doesn't really go | into how he made it work too closely, so it's easy to say it was | a success. The real interesting thing to understand would be, | "Why was it a success versus other approaches?" What really made | it a better choice vs other approaches? What was the team make | up? He says that it made the code easy to understand. To whom? | Interesting the team made it work, but not enough to say, "Sure | let's try it without a lot more forethought." | loldot_ wrote: | Exactly! If you're writing a C compiler, it would probably be a | bad idea to have that logic in a database, though it could be | fun to try. On the other hand if your application is | summarizing a lot data by different dimensions, it would | probably be a bad idea to transfer all that data over the | network only to summarize it in an application layer. Most | applications have a little bit of both though and so will need | both an application layer and database layer. | revskill wrote: | I'm using this pattern on my projects for my customers. | | One of the reason is that my team knows only SQL things, they | don't have time to install other programming tools on their | machine. | | So, just install postgresql and code the logic you want ! | marcosdumay wrote: | The one problem this technique has is that data and software | normally have two very different speed and correctness | requirements. That means that data and software should evolve | following different procedures, what heavily implies that you | want different people working at them, or at least you want | people to look at them at different times. | | For that, you really want independent access controls and CI | tooling. | | Of course, you can't separate much if you are a 1 or 2 people | team at early stages of some project. And it may help you move | faster. | | But: | | > "Rebuilding the database is as simple as executing one line | bash loop (I do it every few minutes)" | | This denounces a very development-centric worldview where | operations and maintenance don't even appear. You can never | rebuild a database, and starting with the delusion that you will | harm you on the future. | capableweb wrote: | > You can never rebuild a database, and starting with the | delusion that you will harm you on the future. | | That seems like a silly assumption. Who's to say you can't use | databases that you can rebuild from scratch whenever you want? | What about append-only logs built with CRDTs and the other | ways? | shuntress wrote: | "rebuilt from scratch" means "as if the production server | just fell into a woodchipper and I'm taking a new one out of | the crate now" | | You __cannot __do that with databases because the __ _data_ | __needs to come from somewhere. | | I'm sure you could implement some kind of echo server in SQL | somehow and yeah that is a "database" that could be rebuilt | from scratch with no loss but that's obviously not the kind | of thing we are talking about here. | taffer wrote: | For this reason you should always separate data and code and | put them into separate schemas. In such a setup, deploying new | code essentially means dropping and re-creating the code schema | in a single transaction. | Roboprog wrote: | Thanks for pointing that out. | | Safe to assume views go in the "code" schema with | procs/funcs/packages, leaving just tables and sequences (if | needed) in the "data" schema? | | Considering building a side project using this kind of | approach... | siscia wrote: | > Performance hint: developers using cursors should have their | hands cut off. This should do the trick. | | What is wrong with cursor? | unklefolk wrote: | Performance basically. As SQL is a set based language you can | often replace cursors (which are basically loops) with joins | and that is orders of magnitude quicker for larger workloads. | mdoms wrote: | I have worked on an application that heavily used sprocs for | business logic. I would not wish it on anyone. It will seem fine | (and actually it will seem better - faster and easier to manage) | while your project is small. | | In a few years when you need to make some major changes you will | see why it was a bad idea, and it will be too late. Have fun | modifying hundreds or thousands of sprocs when you need to make a | large-scale change to the structure of your data, because SQL | won't compose. Have fun modifying dozens of sprocs for each | change in business logic, because SQL won't compose. I guarantee | you will have mountains of duplicated code because SQL won't | compose. | rishav_sharan wrote: | Can you elaborate a bit more on duplicated code/composition | issue? I would think that functions would ensure that there | isn't much duplicated code. | mdoms wrote: | Say for example you need two queries, one for fetching a | paged list of customers ordered by birth date, and one for | fetching a paged list of customers who are male. | | You will find you'll need two queries with a huge amount of | duplicate logic - the SELECT clauses, even if they're pulling | the same columns, will need to be duplicated (don't forget to | keep them in sync when the table changes!), because there's | no reasonable way to compose the query from a common SELECT | clause. The paging logic will be duplicated for the same | reason. So although the queries are similar, only sorted and | filtered differently, you will need to duplicate logic if you | want to avoid pulling the entire data set first and | performing filtering and sorting in separate modules. | | These problems become significantly worse when you're talking | about inserting, updating or upserting data that involves | validation and business rules. These rules are not only more | difficult to implement in SQL, but they change more often | than the structure of data (in most cases) so the duplication | becomes a huge issue. | | I haven't tried this on a system that uses Postgres functions | so I could be way off base here, my experience was pure | sprocs in MS SQL. | panarky wrote: | Views help with this. | | Write one view for selecting customers, with all the joins, | sub-queries and case-when logic. | | Then select from this view order by birth date, and select | from the same view by sex. | | Yes, the limit/offset paging clause will be duplicated, but | all the joins, sub-queries and case-when stuff can be DRY'd | in a single view. | kqr wrote: | I agree. To me this sounds more like bad programming (high | coupling and low cohesion) and like it would be a problem | even if a separate application acted as the backend. | aaomidi wrote: | Well some systems make good programming really difficult. | Stored procedures, especially back then.... Yeah. | throwaway894345 wrote: | I believe this in the abstract, but would be very | interested in some concrete explanation for why sprocs | compose worse than other programming languages. How would | the OP's situation have improved if instead of sprocs he | had a similarly complex webapp and had to deal with the | schema changes there? I'm not challenging the OP; I don't | have enough experience with sprocs to have an informed | opinion, but this information is necessary to make sense | of the OP's criticism. | | The best argument against sprocs that I've heard is that | you really don't want any code running on your database | hosts that you don't absolutely need because it steals | CPU cycles from those hosts and they don't scale | horizontally as well as stateless web servers. This is a | completely different argument than the OP's, however. | cameronh90 wrote: | Databases are engineered for high reliability - data | integrity above all else. That means they develop more | slowly and are perpetually behind what you expect from a | modern programming language. | | If someone created a database with the intention of it | being a good development framework, it would probably be | more pleasurable to code against, but would you trust it | with your data? | aszen wrote: | Becuase of lack of tooling there is tons of duplicate logic | in SQL based systems, I see the same logic repeated across | queries which already exists in some view but no knows about | it so it ends up being repeated. Lack of abstractions like | modules and namespaces for logically grouping stored | procedures makes it hard to understand where is what | fiddlerwoaroof wrote: | Every database I've used has namespaces: most application | code ignores SQL schemas, but that's what they're for. | [deleted] | cneu wrote: | 21 years ago, I joined a young team that wrote an ERP, with all | business logic in PL/SQL. Customers are still amazed how fast | these guys are going. 10 years ago I joined Oracle to work on | APEX (created in 1999), which is a web app development and | runtime environment, written in PL/SQL. We estimate that there | are about 260K developers world-wide who are developing apps | with APEX. All of their business logic is also on the server. | Call me biased because I am working for the man, but my data | points are completely different. | sbuttgereit wrote: | I worked with two other ERP class systems that did this, one | using Oracle (with an Oracle Forms/Reports front-end), the | other PostgreSQL. | | I can confirm your experience. There's no doubt that stored | procedure/function based business logic requires a certain | discipline, knowledge set, and the ability to get a team in | marching in the same direction. But if you can achieve the | organizational discipline to make it work there are definite | advantages, especially in the ERP space. | | And that may well be differentiator... those of us working | with more traditional business systems have trade-offs that | you won't find in a startup. For example, a COTS ERP system | is more likely to not really be a single "application", but a | bunch of applications sharing data. This means a lot of | application servers, integrations, etc., not all from the | people that made the ERP, needing access to the ERP data. The | easiest integration is often at the database, especially | since you can have technology from different decades (and | made according to the fashions of their time) needing to | access that one common denominator. Since many ERP systems | are built on traditional RDBMSs, and talking to those doesn't | change much over long periods of time... having the logic be | there to make these best of breed systems work sensibly with | the ERP can be very helpful. All that said, in this context | I'm an advocate of the approach. | | Now, take a team that maybe has a high churn, sees the | database as some dark and frighting mystical power that can | only safely be approached with an ORM, or a team that thinks | their "cowboy coding" is their core strength (if perhaps not | that thought directly) and database based business logic | certainly has many foot-guns. But, there are really few | technologies that don't suffer without a good well-rounded, | consistent approach. | piyh wrote: | I developed an application on APEX to make a new front end | for our old payroll database. Thanks for making my life | easier. | zubairq wrote: | I agree, Apex is awesome. Oracle Apex being written in stored | procedures was actually a big inspiration for a low code tool | project I did myself, which while not being written in stored | procedures took alot of other ideas from Apex (I was an | Oracle Apex developer for 4 years) | cneu wrote: | Cool, good luck with your project! | xupybd wrote: | I have seen large database heavy apps. They are the cleanest | I've ever worked with. I've had no trouble composing SQL. I | can't think of one example where this has been an issue. You | need to rely on views, functions and tables to store your | business rules and look up the rules. | | The big down side I see is the learning curve. Writing business | logic in the database is not easy and not easy to maintain. It | can take half a day to grow a large function. Even longer to | debug sometimes. But you learn to structure things well. | ak39 wrote: | If you write your views, tvf and stored procedures to use | common elements defined once and once only (this starts with | once and once only _tables_ ), maintenance is easy peasy. If | you let every developer create their own view for the same | business logic, then you are creating an unmanageable creature. | | This also applies to "composable" code written in the | application layer outside the database. | LukeShu wrote: | That's the approach that https://crt.sh uses. | | https://www.lukeshu.com/blog/crt-sh-architecture.html | dang wrote: | jgrahamc wrote a fascinating comment about how Cloudflare started | this way: https://news.ycombinator.com/item?id=22883548 | njkleiner wrote: | Related: https://sive.rs/pg | notJim wrote: | See also | | https://www.slideshare.net/beamrider9/scaling-etsy-what-went... | | https://www.youtube.com/watch?v=eenrfm50mXw ___________________________________________________________________ (page generated 2020-12-03 23:01 UTC)