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

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 

Recently uploaded (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

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