SlideShare a Scribd company logo
1 of 38
Postgres FTW
 1: Postgres is just easier
http://www.slideshare.net/gisborne/postgres-is-easier
Data Types
•   Boolean (!)
•   Numeric
    •   up to 131072 digits before decimal;
        16383 digits after (MySQL: 65 digits)
•   Network address
    broadcast('192.168.1.5/24')
    hostmask('192.168.23.20/30')
•   UUID
•   XML
•   Geometric (point, line, rectangle, circle,
    path, polygon)
•   JSON (in 9.2, later in 2012)
Data Types
•   Make your own!
    CREATE TYPE inventory_item AS (
    ! name            text,
    ! supplier_id     integer,
    ! price           numeric);

    CREATE TABLE on_hand (
    ! item      inventory_item,
    ! count     integer);

    INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
    SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
Custom Functions
CREATE FUNCTION price_extension(
! inventory_item,
! integer)
RETURNS
! numeric
AS '
! SELECT
! ! $1.price * $2'
LANGUAGE SQL;

SELECT price_extension(item, 10) FROM on_hand;
Functions! (Statistical)
corr(Y, X)             regr_sxx(Y, X)
covar_pop(Y, X)        regr_sxy(Y, X)
covar_samp(Y, X)       regr_syy(Y, X)
regr_avgx(Y, X)        stddev(expression)
regr_avgy(Y, X)        stddev_pop(expression)
regr_count(Y, X)       stddev_samp(expression)
regr_intercept(Y, X)   variance(expression)
regr_r2(Y, X)          var_pop(expression)
regr_slope(Y, X)       var_samp(expression)
Functions! (Statistical)
                                                 MySQL:
corr(Y, X)             regr_sxx(Y, X)
                                                 MAX()
covar_pop(Y, X)        regr_sxy(Y, X)
                                                 MIN()
covar_samp(Y, X)       regr_syy(Y, X)            STD()
regr_avgx(Y, X)        stddev(expression)        STDDEV_POP()
regr_avgy(Y, X)        stddev_pop(expression)    STDDEV_SAMP()
regr_count(Y, X)       stddev_samp(expression)   STDDEV()

regr_intercept(Y, X)   variance(expression)      SUM()
                                                 VAR_POP()
regr_r2(Y, X)          var_pop(expression)
                                                 VAR_SAMP()
regr_slope(Y, X)       var_samp(expression)
                                                 VARIANCE()
Functions! (Text Search)
•   Very fast index updates   • Search terms in context
                                 (shows how your search
•   Proximity                    terms are used in
•   Weighting scheme             context)

•   Stemming                  • Regex, substring etc
•   Stopwords
•   Modular architecture
    (add parsers and
    dictionaries)
• Multilingual support
Functions! (Text Search)
•   Very fast index updates   • Search terms in context   MySQL:
                                 (shows how your search
•   Proximity                    terms are used in        Regex, substring, etc
•   Weighting scheme             context)

•   Stemming                  • Regex, substring etc
•   Stopwords
•   Modular architecture
    (add parsers and
    dictionaries)
• Multilingual support
Functions! (Window Functions)
•   Aggregate values from single rows

•   Perform GROUP BY calculations, BUT leave rows intact
Functions! (Window Functions)
Functions! (Window Functions)
Any aggregate function:
    SELECT name, salary, salary / (avg(salary) OVER (PARTITION BY depname)) FROM employee
Functions! (Window Functions)
Any aggregate function:
    SELECT name, salary, salary / (avg(salary) OVER (PARTITION BY depname)) FROM employee



Special window functions:
    SELECT name, rank() OVER (PARTITION BY department_id ORDER BY hire_date ASC) FROM employee
Common Table Expressions
•   Like a local view; or

•   Like a named subquery (or named INSERT, DELETE etc)
Common Table Expressions
Simplify subqueries:
  WITH                               SELECT
  ! regional_sales AS (              ! region,
  ! ! SELECT                         ! product,
  ! ! ! region,                      ! SUM(quantity) AS product_units,
  ! ! ! SUM(amount) AS total_sales   ! SUM(amount) AS product_sales
  ! ! FROM                           FROM
  ! ! ! orders                       ! orders
     ! GROUP BY                      WHERE
  ! ! ! region),                     ! region IN (
  ! top_regions AS (                 ! ! SELECT
  ! ! SELECT                         ! ! ! region
  ! ! ! region                       ! ! FROM
  ! ! FROM                           ! ! ! top_regions)
  ! ! ! regional_sales               GROUP BY
  ! ! WHERE                          ! region,
  ! ! ! total_sales > (              ! product;
  ! ! ! ! SELECT
  ! ! ! ! ! SUM(total_sales)/10
  ! ! ! ! FROM
  ! ! ! ! ! regional_sales))
Common Table Expressions
Recursive queries:
  WITH RECURSIVE
  ! t(n) AS (
  ! ! ! VALUES (1)
  ! ! UNION ALL
  ! ! ! SELECT
  ! ! ! ! n+1
  ! ! ! FROM
  ! ! ! ! t
  ! ! ! WHERE
  ! ! ! ! n < 100)
  SELECT
  ! sum(n)
  FROM
  ! t;
Common Table Expressions
Recursive queries:
  WITH RECURSIVE
  ! search_graph(id, link, data, depth) AS (
  ! ! ! SELECT
  ! ! ! ! g.id,
  ! ! ! ! g.link,
  ! ! ! ! g.data,
  ! ! ! ! 1
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL
  ! ! ! SELECT
  ! ! ! ! g.id,
  ! ! ! ! g.link,
  ! ! ! ! g.data,
  ! ! ! ! sg.depth + 1
  ! ! ! FROM
  ! ! ! ! graph g,
  ! ! ! ! search_graph sg
  ! ! ! WHERE
  ! ! ! ! g.id = sg.link)
  SELECT * FROM search_graph;
Common Table Expressions
Recursive queries:
  WITH RECURSIVE
  ! search_graph(id, link, data, depth) AS (
  ! ! ! SELECT
  ! ! ! ! g.id,
  ! ! ! ! g.link,
                                              cl es!
  ! ! ! ! g.data,
                                            cy
  ! ! ! ! 1
                                      w ith
                               ails
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL            F
  ! ! ! SELECT
  ! ! ! ! g.id,
  ! ! ! ! g.link,
  ! ! ! ! g.data,
  ! ! ! ! sg.depth + 1
  ! ! ! FROM
  ! ! ! ! graph g,
  ! ! ! ! search_graph sg
  ! ! ! WHERE
  ! ! ! ! g.id = sg.link)
  SELECT * FROM search_graph;
Common Table Expressions
Recursive queries:
  WITH RECURSIVE         !   !   !SELECT
  ! search_graph(        !   !   !! g.id,
  ! ! id,                !   !   !! g.link,
  ! ! link,              !   !   !! g.data,
  ! ! data,              !   !   !! sg.depth + 1,
  ! ! depth,             !   !   !! path || g.id,
  ! ! path,              !   !   !! g.id = ANY(path)
  ! ! cycle) AS (                !FROM
  ! ! ! SELECT           ! ! ! ! graph g,
  ! ! ! ! g.id,          ! ! ! ! search_graph sg
  ! ! ! ! g.link,        ! ! ! WHERE
  ! ! ! ! g.data,        ! ! ! ! g.id = sg.link AND
  ! ! ! ! 1,             ! ! ! ! NOT cycle)
  ! ! ! ! ARRAY[g.id],   SELECT * FROM search_graph;
  ! ! ! ! false
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL
Common Table Expressions
Recursive queries:
  WITH RECURSIVE         !   !   !SELECT
  ! search_graph(        !   !   !! g.id,
  ! ! id,                !   !   !! g.link,
  ! ! link,              !   !   !! g.data,
  ! ! data,              !   !   !! sg.depth + 1,
  ! ! depth,             !   !   !! path || g.id,
  ! ! path,              !   !   !! g.id = ANY(path)
  ! ! cycle) AS (                !FROM
  ! ! ! SELECT           ! ! ! ! graph g,
  ! ! ! ! g.id,          ! ! ! ! search_graph sg
  ! ! ! ! g.link,        ! ! ! WHERE
  ! ! ! ! g.data,        ! ! ! ! g.id = sg.link AND
  ! ! ! ! 1,             ! ! ! ! NOT cycle)
  ! ! ! ! ARRAY[g.id],   SELECT * FROM search_graph;
  ! ! ! ! false
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL
Common Table Expressions
Recursive queries:
  WITH RECURSIVE         !   !   !SELECT
  ! search_graph(        !   !   !! g.id,
  ! ! id,                !   !   !! g.link,
  ! ! link,              !   !   !! g.data,
  ! ! data,              !   !   !! sg.depth + 1,
  ! ! depth,             !   !   !! path || g.id,
  ! ! path,              !   !   !! g.id = ANY(path)
  ! ! cycle) AS (                !FROM
  ! ! ! SELECT           ! ! ! ! graph g,
  ! ! ! ! g.id,          ! ! ! ! search_graph sg
  ! ! ! ! g.link,        ! ! ! WHERE
  ! ! ! ! g.data,        ! ! ! ! g.id = sg.link AND
  ! ! ! ! 1,             ! ! ! ! NOT cycle)
  ! ! ! ! ARRAY[g.id],   SELECT * FROM search_graph;
  ! ! ! ! false
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL
Common Table Expressions
Recursive queries:
  WITH RECURSIVE         !   !   !SELECT
  ! search_graph(        !   !   !! g.id,
  ! ! id,                !   !   !! g.link,
  ! ! link,              !   !   !! g.data,
  ! ! data,              !   !   !! sg.depth + 1,
  ! ! depth,             !   !   !! path || g.id,
  ! ! path,              !   !   !! g.id = ANY(path)
  ! ! cycle) AS (                !FROM
  ! ! ! SELECT           ! ! ! ! graph g,
  ! ! ! ! g.id,          ! ! ! ! search_graph sg
  ! ! ! ! g.link,        ! ! ! WHERE
  ! ! ! ! g.data,        ! ! ! ! g.id = sg.link AND
  ! ! ! ! 1,             ! ! ! ! NOT cycle)
  ! ! ! ! ARRAY[g.id],   SELECT * FROM search_graph;
  ! ! ! ! false
  ! ! ! FROM
  ! ! ! ! graph g
        UNION ALL
Common Table Expressions
Modifying data:
  WITH
  ! moved_rows AS (
  ! ! DELETE
  ! ! FROM
  ! ! ! products
  ! ! WHERE
  ! ! ! "date" >= '2010-10-01' AND
  ! ! ! "date" < '2010-11-01'
       ! RETURNING *)
  INSERT INTO
  ! products_log
  SELECT
  ! *
  FROM
  ! moved_rows;
Small but big features
Small but big features
•   Index in the background
Small but big features
•   Index in the background

•   Transactional schema changes
Small but big features
•   Index in the background

•   Transactional schema changes

•   Fast schema changes
Small but big features
•   Index in the background

•   Transactional schema changes

•   Fast schema changes

    •   Drop column instantly
Small but big features
•   Index in the background

•   Transactional schema changes

•   Fast schema changes

    •   Drop column instantly

    •   Add column instantly (unless default value)
NoSQL?
NoSQL in your SQL (Arrays)
•   Array type
    CREATE TABLE sal_emp (              INSERT INTO
    ! name             text,            ! sal_emp
    ! pay_by_quarter integer[],         VALUES (
    ! schedule         text[][]);       ! 'Carol',
                                        ! '{20000, 25000, 25000, 25000}',
    INSERT INTO                         ! '{
    ! sal_emp                           ! ! {"breakfast", "consulting"},
    VALUES (                            ! ! {"meeting", "lunch"}
    ! 'Bill',                           ! }');
    ! '{10000, 10000, 10000, 10000}',
    ! '{
    ! ! {"meeting", "lunch"},
    ! ! {"training", "presentation"}
    ! }');
NoSQL in your SQL (Arrays)
SELECT * FROM sal_emp;
 name |       pay_by_quarter       |                 schedule
-------+---------------------------+-------------------------------------------
 Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
 Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
(2 rows)

SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2];
 name
-------
 Carol
(1 row)
NoSQL in your SQL (Arrays)
SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
        schedule
------------------------
 {{meeting},{training}}
(1 row)

SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter);

ARRAY[1,4,3] @> ARRAY[3,1]
NoSQL in your SQL (Arrays)
SELECT
!   buyer,
!   SUM(total),
!   ARRAY_AGG(order_date ORDER BY total DESC)
FROM
!   orders
GROUP BY
!   buyer;

buyer | sum | array_agg
------+------+-------------------------------------------------------------------
Alice | 1057 | {2009-05-08,2009-08-15,2009-03-25,2009-08-16}
Bob   | 905 | {2009-02-10,2009-01-29,2009-08-17,2009-05-12,2009-08-22,2009-05-28}
Carol | 1118 | {2009-04-28,2009-09-01,2009-03-30,2009-06-27-01-10,2009-09-06}
Dave | 1239 | {2009-05-28,2009-07-27,2009-02-07,2009-07-15,2009-08-27}
Eve   | 1222 | {2009-02-01,2009-08-14,2009-09-26,2009-04-07-10-02}
(5 rows)
NoSQL in your SQL (HStore)
Key-value store:
create_table :products do |t|
! t.string :name
! t.hstore :data
! t.timestamps
end

gem install activerecord-postgres-hstore

Product.create(
! name: "Geek Love: A Novel",
   data: {'author' => 'Katherine Dunn', 'pages' => 368, 'category' => 'fiction'})

Product.last.data['category']   # => 'fiction'
NoSQL in your SQL (HStore)
# Find all products that have a key of 'author' in data
Product.where("data ? :key", :key => 'author')

# Find all products that have a 'pages' and '368' key value pair in data
Product.where("data @> (:key => :value)", :key => 'pages', :value => '368')

# Find all products that don't have a key value pair 'pages' and '999' in data
Product.where("not data @> (:key => :value)", :key => 'pages', :value => '999')

# Find all products having key 'author' and value like 'ba' in data
Product.where("data -> :key LIKE :value",     :key => 'author, :value => "%Kat%")
Use a really good language
CREATE FUNCTION tu(varchar)
RETURNS setof record
AS '
!   size = PL.column_name(args[0]).size
!   res = nil
!   PL::Plan.new("select * from #{args[0]}", 'block' => 50).each do |row|
!   ! if res.nil?
!   ! ! res = row.values
!   ! else
!   ! ! res.concat row.values
!   ! ! yield res
!   ! ! res = nil
!   ! end
!   end
!   if res
!   ! res.concat Array.new(size)
!   ! yield res
!   end
' language 'plruby';

CREATE FUNCTION
FIN
http://www.slideshare.net/gisborne/postgres-is-easier


                          guyren@relevantlogic.com
                           http://relevantlogic.com

More Related Content

Similar to Postgres is easier

The Marvelous Land of Higher Order Functions
The Marvelous Land of Higher Order FunctionsThe Marvelous Land of Higher Order Functions
The Marvelous Land of Higher Order FunctionsMike Harris
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!Gautam Rege
 
Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0Jeremy Gillick
 
20th.陈晓鸣 百度海量日志分析架构及处理经验分享
20th.陈晓鸣 百度海量日志分析架构及处理经验分享20th.陈晓鸣 百度海量日志分析架构及处理经验分享
20th.陈晓鸣 百度海量日志分析架构及处理经验分享elevenma
 
Searching Images by Color: Presented by Chris Becker, Shutterstock
Searching Images by Color: Presented by Chris Becker, ShutterstockSearching Images by Color: Presented by Chris Becker, Shutterstock
Searching Images by Color: Presented by Chris Becker, ShutterstockLucidworks
 
Programming Paradigms Which One Is The Best?
Programming Paradigms Which One Is The Best?Programming Paradigms Which One Is The Best?
Programming Paradigms Which One Is The Best?Netguru
 
HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析Takahiro Inoue
 
F# at GameSys
F# at GameSysF# at GameSys
F# at GameSysYan Cui
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGISmleslie
 
Building A Database Driven Website Using Php & My Sql
Building A Database Driven Website Using Php & My SqlBuilding A Database Driven Website Using Php & My Sql
Building A Database Driven Website Using Php & My Sqlyufypang
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
SLES11で構築するXen仮想化+HAクラスタ入門
SLES11で構築するXen仮想化+HAクラスタ入門SLES11で構築するXen仮想化+HAクラスタ入門
SLES11で構築するXen仮想化+HAクラスタ入門VirtualTech Japan Inc.
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhDIVYA SINGH
 
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und Erfahrungen
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und ErfahrungenOSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und Erfahrungen
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und ErfahrungenNETWAYS
 
Building_a_database_with_PHP_and_SQL
Building_a_database_with_PHP_and_SQLBuilding_a_database_with_PHP_and_SQL
Building_a_database_with_PHP_and_SQLHoàng Hải Nguyễn
 
Clojure: Simple By Design
Clojure: Simple By DesignClojure: Simple By Design
Clojure: Simple By DesignAll Things Open
 
Some cool features of MongoDB
Some cool features of MongoDBSome cool features of MongoDB
Some cool features of MongoDBTugdual Grall
 

Similar to Postgres is easier (20)

The Marvelous Land of Higher Order Functions
The Marvelous Land of Higher Order FunctionsThe Marvelous Land of Higher Order Functions
The Marvelous Land of Higher Order Functions
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!
 
Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0Feed Normalization with Ember Data 1.0
Feed Normalization with Ember Data 1.0
 
20th.陈晓鸣 百度海量日志分析架构及处理经验分享
20th.陈晓鸣 百度海量日志分析架构及处理经验分享20th.陈晓鸣 百度海量日志分析架构及处理经验分享
20th.陈晓鸣 百度海量日志分析架构及处理经验分享
 
Searching Images by Color: Presented by Chris Becker, Shutterstock
Searching Images by Color: Presented by Chris Becker, ShutterstockSearching Images by Color: Presented by Chris Becker, Shutterstock
Searching Images by Color: Presented by Chris Becker, Shutterstock
 
Programming Paradigms Which One Is The Best?
Programming Paradigms Which One Is The Best?Programming Paradigms Which One Is The Best?
Programming Paradigms Which One Is The Best?
 
HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析HadoopとMongoDBを活用したソーシャルアプリのログ解析
HadoopとMongoDBを活用したソーシャルアプリのログ解析
 
F# at GameSys
F# at GameSysF# at GameSys
F# at GameSys
 
Intro To PostGIS
Intro To PostGISIntro To PostGIS
Intro To PostGIS
 
ภาษา C
ภาษา Cภาษา C
ภาษา C
 
Building A Database Driven Website Using Php & My Sql
Building A Database Driven Website Using Php & My SqlBuilding A Database Driven Website Using Php & My Sql
Building A Database Driven Website Using Php & My Sql
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
SLES11で構築するXen仮想化+HAクラスタ入門
SLES11で構築するXen仮想化+HAクラスタ入門SLES11で構築するXen仮想化+HAクラスタ入門
SLES11で構築するXen仮想化+HAクラスタ入門
 
Mcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singhMcs011 solved assignment by divya singh
Mcs011 solved assignment by divya singh
 
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und Erfahrungen
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und ErfahrungenOSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und Erfahrungen
OSDC 2011 | NoSQL in der Cloud: Patterns, Architektur und Erfahrungen
 
Building_a_database_with_PHP_and_SQL
Building_a_database_with_PHP_and_SQLBuilding_a_database_with_PHP_and_SQL
Building_a_database_with_PHP_and_SQL
 
Rug hogan-10-03-2012
Rug hogan-10-03-2012Rug hogan-10-03-2012
Rug hogan-10-03-2012
 
Clojure: Simple By Design
Clojure: Simple By DesignClojure: Simple By Design
Clojure: Simple By Design
 
Hadoop london
Hadoop londonHadoop london
Hadoop london
 
Some cool features of MongoDB
Some cool features of MongoDBSome cool features of MongoDB
Some cool features of MongoDB
 

Recently uploaded

Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Recently uploaded (20)

Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

Postgres is easier

  • 1. Postgres FTW 1: Postgres is just easier
  • 3. Data Types • Boolean (!) • Numeric • up to 131072 digits before decimal; 16383 digits after (MySQL: 65 digits) • Network address broadcast('192.168.1.5/24') hostmask('192.168.23.20/30') • UUID • XML • Geometric (point, line, rectangle, circle, path, polygon) • JSON (in 9.2, later in 2012)
  • 4. Data Types • Make your own! CREATE TYPE inventory_item AS ( ! name text, ! supplier_id integer, ! price numeric); CREATE TABLE on_hand ( ! item inventory_item, ! count integer); INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000); SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
  • 5. Custom Functions CREATE FUNCTION price_extension( ! inventory_item, ! integer) RETURNS ! numeric AS ' ! SELECT ! ! $1.price * $2' LANGUAGE SQL; SELECT price_extension(item, 10) FROM on_hand;
  • 6. Functions! (Statistical) corr(Y, X) regr_sxx(Y, X) covar_pop(Y, X) regr_sxy(Y, X) covar_samp(Y, X) regr_syy(Y, X) regr_avgx(Y, X) stddev(expression) regr_avgy(Y, X) stddev_pop(expression) regr_count(Y, X) stddev_samp(expression) regr_intercept(Y, X) variance(expression) regr_r2(Y, X) var_pop(expression) regr_slope(Y, X) var_samp(expression)
  • 7. Functions! (Statistical) MySQL: corr(Y, X) regr_sxx(Y, X) MAX() covar_pop(Y, X) regr_sxy(Y, X) MIN() covar_samp(Y, X) regr_syy(Y, X) STD() regr_avgx(Y, X) stddev(expression) STDDEV_POP() regr_avgy(Y, X) stddev_pop(expression) STDDEV_SAMP() regr_count(Y, X) stddev_samp(expression) STDDEV() regr_intercept(Y, X) variance(expression) SUM() VAR_POP() regr_r2(Y, X) var_pop(expression) VAR_SAMP() regr_slope(Y, X) var_samp(expression) VARIANCE()
  • 8. Functions! (Text Search) • Very fast index updates • Search terms in context (shows how your search • Proximity terms are used in • Weighting scheme context) • Stemming • Regex, substring etc • Stopwords • Modular architecture (add parsers and dictionaries) • Multilingual support
  • 9. Functions! (Text Search) • Very fast index updates • Search terms in context MySQL: (shows how your search • Proximity terms are used in Regex, substring, etc • Weighting scheme context) • Stemming • Regex, substring etc • Stopwords • Modular architecture (add parsers and dictionaries) • Multilingual support
  • 10. Functions! (Window Functions) • Aggregate values from single rows • Perform GROUP BY calculations, BUT leave rows intact
  • 12. Functions! (Window Functions) Any aggregate function: SELECT name, salary, salary / (avg(salary) OVER (PARTITION BY depname)) FROM employee
  • 13. Functions! (Window Functions) Any aggregate function: SELECT name, salary, salary / (avg(salary) OVER (PARTITION BY depname)) FROM employee Special window functions: SELECT name, rank() OVER (PARTITION BY department_id ORDER BY hire_date ASC) FROM employee
  • 14. Common Table Expressions • Like a local view; or • Like a named subquery (or named INSERT, DELETE etc)
  • 15. Common Table Expressions Simplify subqueries: WITH SELECT ! regional_sales AS ( ! region, ! ! SELECT ! product, ! ! ! region, ! SUM(quantity) AS product_units, ! ! ! SUM(amount) AS total_sales ! SUM(amount) AS product_sales ! ! FROM FROM ! ! ! orders ! orders ! GROUP BY WHERE ! ! ! region), ! region IN ( ! top_regions AS ( ! ! SELECT ! ! SELECT ! ! ! region ! ! ! region ! ! FROM ! ! FROM ! ! ! top_regions) ! ! ! regional_sales GROUP BY ! ! WHERE ! region, ! ! ! total_sales > ( ! product; ! ! ! ! SELECT ! ! ! ! ! SUM(total_sales)/10 ! ! ! ! FROM ! ! ! ! ! regional_sales))
  • 16. Common Table Expressions Recursive queries: WITH RECURSIVE ! t(n) AS ( ! ! ! VALUES (1) ! ! UNION ALL ! ! ! SELECT ! ! ! ! n+1 ! ! ! FROM ! ! ! ! t ! ! ! WHERE ! ! ! ! n < 100) SELECT ! sum(n) FROM ! t;
  • 17. Common Table Expressions Recursive queries: WITH RECURSIVE ! search_graph(id, link, data, depth) AS ( ! ! ! SELECT ! ! ! ! g.id, ! ! ! ! g.link, ! ! ! ! g.data, ! ! ! ! 1 ! ! ! FROM ! ! ! ! graph g UNION ALL ! ! ! SELECT ! ! ! ! g.id, ! ! ! ! g.link, ! ! ! ! g.data, ! ! ! ! sg.depth + 1 ! ! ! FROM ! ! ! ! graph g, ! ! ! ! search_graph sg ! ! ! WHERE ! ! ! ! g.id = sg.link) SELECT * FROM search_graph;
  • 18. Common Table Expressions Recursive queries: WITH RECURSIVE ! search_graph(id, link, data, depth) AS ( ! ! ! SELECT ! ! ! ! g.id, ! ! ! ! g.link, cl es! ! ! ! ! g.data, cy ! ! ! ! 1 w ith ails ! ! ! FROM ! ! ! ! graph g UNION ALL F ! ! ! SELECT ! ! ! ! g.id, ! ! ! ! g.link, ! ! ! ! g.data, ! ! ! ! sg.depth + 1 ! ! ! FROM ! ! ! ! graph g, ! ! ! ! search_graph sg ! ! ! WHERE ! ! ! ! g.id = sg.link) SELECT * FROM search_graph;
  • 19. Common Table Expressions Recursive queries: WITH RECURSIVE ! ! !SELECT ! search_graph( ! ! !! g.id, ! ! id, ! ! !! g.link, ! ! link, ! ! !! g.data, ! ! data, ! ! !! sg.depth + 1, ! ! depth, ! ! !! path || g.id, ! ! path, ! ! !! g.id = ANY(path) ! ! cycle) AS ( !FROM ! ! ! SELECT ! ! ! ! graph g, ! ! ! ! g.id, ! ! ! ! search_graph sg ! ! ! ! g.link, ! ! ! WHERE ! ! ! ! g.data, ! ! ! ! g.id = sg.link AND ! ! ! ! 1, ! ! ! ! NOT cycle) ! ! ! ! ARRAY[g.id], SELECT * FROM search_graph; ! ! ! ! false ! ! ! FROM ! ! ! ! graph g UNION ALL
  • 20. Common Table Expressions Recursive queries: WITH RECURSIVE ! ! !SELECT ! search_graph( ! ! !! g.id, ! ! id, ! ! !! g.link, ! ! link, ! ! !! g.data, ! ! data, ! ! !! sg.depth + 1, ! ! depth, ! ! !! path || g.id, ! ! path, ! ! !! g.id = ANY(path) ! ! cycle) AS ( !FROM ! ! ! SELECT ! ! ! ! graph g, ! ! ! ! g.id, ! ! ! ! search_graph sg ! ! ! ! g.link, ! ! ! WHERE ! ! ! ! g.data, ! ! ! ! g.id = sg.link AND ! ! ! ! 1, ! ! ! ! NOT cycle) ! ! ! ! ARRAY[g.id], SELECT * FROM search_graph; ! ! ! ! false ! ! ! FROM ! ! ! ! graph g UNION ALL
  • 21. Common Table Expressions Recursive queries: WITH RECURSIVE ! ! !SELECT ! search_graph( ! ! !! g.id, ! ! id, ! ! !! g.link, ! ! link, ! ! !! g.data, ! ! data, ! ! !! sg.depth + 1, ! ! depth, ! ! !! path || g.id, ! ! path, ! ! !! g.id = ANY(path) ! ! cycle) AS ( !FROM ! ! ! SELECT ! ! ! ! graph g, ! ! ! ! g.id, ! ! ! ! search_graph sg ! ! ! ! g.link, ! ! ! WHERE ! ! ! ! g.data, ! ! ! ! g.id = sg.link AND ! ! ! ! 1, ! ! ! ! NOT cycle) ! ! ! ! ARRAY[g.id], SELECT * FROM search_graph; ! ! ! ! false ! ! ! FROM ! ! ! ! graph g UNION ALL
  • 22. Common Table Expressions Recursive queries: WITH RECURSIVE ! ! !SELECT ! search_graph( ! ! !! g.id, ! ! id, ! ! !! g.link, ! ! link, ! ! !! g.data, ! ! data, ! ! !! sg.depth + 1, ! ! depth, ! ! !! path || g.id, ! ! path, ! ! !! g.id = ANY(path) ! ! cycle) AS ( !FROM ! ! ! SELECT ! ! ! ! graph g, ! ! ! ! g.id, ! ! ! ! search_graph sg ! ! ! ! g.link, ! ! ! WHERE ! ! ! ! g.data, ! ! ! ! g.id = sg.link AND ! ! ! ! 1, ! ! ! ! NOT cycle) ! ! ! ! ARRAY[g.id], SELECT * FROM search_graph; ! ! ! ! false ! ! ! FROM ! ! ! ! graph g UNION ALL
  • 23. Common Table Expressions Modifying data: WITH ! moved_rows AS ( ! ! DELETE ! ! FROM ! ! ! products ! ! WHERE ! ! ! "date" >= '2010-10-01' AND ! ! ! "date" < '2010-11-01' ! RETURNING *) INSERT INTO ! products_log SELECT ! * FROM ! moved_rows;
  • 24. Small but big features
  • 25. Small but big features • Index in the background
  • 26. Small but big features • Index in the background • Transactional schema changes
  • 27. Small but big features • Index in the background • Transactional schema changes • Fast schema changes
  • 28. Small but big features • Index in the background • Transactional schema changes • Fast schema changes • Drop column instantly
  • 29. Small but big features • Index in the background • Transactional schema changes • Fast schema changes • Drop column instantly • Add column instantly (unless default value)
  • 31. NoSQL in your SQL (Arrays) • Array type CREATE TABLE sal_emp ( INSERT INTO ! name text, ! sal_emp ! pay_by_quarter integer[], VALUES ( ! schedule text[][]); ! 'Carol', ! '{20000, 25000, 25000, 25000}', INSERT INTO ! '{ ! sal_emp ! ! {"breakfast", "consulting"}, VALUES ( ! ! {"meeting", "lunch"} ! 'Bill', ! }'); ! '{10000, 10000, 10000, 10000}', ! '{ ! ! {"meeting", "lunch"}, ! ! {"training", "presentation"} ! }');
  • 32. NoSQL in your SQL (Arrays) SELECT * FROM sal_emp; name | pay_by_quarter | schedule -------+---------------------------+------------------------------------------- Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}} Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}} (2 rows) SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2]; name ------- Carol (1 row)
  • 33. NoSQL in your SQL (Arrays) SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill'; schedule ------------------------ {{meeting},{training}} (1 row) SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter); ARRAY[1,4,3] @> ARRAY[3,1]
  • 34. NoSQL in your SQL (Arrays) SELECT ! buyer, ! SUM(total), ! ARRAY_AGG(order_date ORDER BY total DESC) FROM ! orders GROUP BY ! buyer; buyer | sum | array_agg ------+------+------------------------------------------------------------------- Alice | 1057 | {2009-05-08,2009-08-15,2009-03-25,2009-08-16} Bob | 905 | {2009-02-10,2009-01-29,2009-08-17,2009-05-12,2009-08-22,2009-05-28} Carol | 1118 | {2009-04-28,2009-09-01,2009-03-30,2009-06-27-01-10,2009-09-06} Dave | 1239 | {2009-05-28,2009-07-27,2009-02-07,2009-07-15,2009-08-27} Eve | 1222 | {2009-02-01,2009-08-14,2009-09-26,2009-04-07-10-02} (5 rows)
  • 35. NoSQL in your SQL (HStore) Key-value store: create_table :products do |t| ! t.string :name ! t.hstore :data ! t.timestamps end gem install activerecord-postgres-hstore Product.create( ! name: "Geek Love: A Novel", data: {'author' => 'Katherine Dunn', 'pages' => 368, 'category' => 'fiction'}) Product.last.data['category'] # => 'fiction'
  • 36. NoSQL in your SQL (HStore) # Find all products that have a key of 'author' in data Product.where("data ? :key", :key => 'author') # Find all products that have a 'pages' and '368' key value pair in data Product.where("data @> (:key => :value)", :key => 'pages', :value => '368') # Find all products that don't have a key value pair 'pages' and '999' in data Product.where("not data @> (:key => :value)", :key => 'pages', :value => '999') # Find all products having key 'author' and value like 'ba' in data Product.where("data -> :key LIKE :value", :key => 'author, :value => "%Kat%")
  • 37. Use a really good language CREATE FUNCTION tu(varchar) RETURNS setof record AS ' ! size = PL.column_name(args[0]).size ! res = nil ! PL::Plan.new("select * from #{args[0]}", 'block' => 50).each do |row| ! ! if res.nil? ! ! ! res = row.values ! ! else ! ! ! res.concat row.values ! ! ! yield res ! ! ! res = nil ! ! end ! end ! if res ! ! res.concat Array.new(size) ! ! yield res ! end ' language 'plruby'; CREATE FUNCTION
  • 38. FIN http://www.slideshare.net/gisborne/postgres-is-easier guyren@relevantlogic.com http://relevantlogic.com

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n