<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code42 &#187; Bazy danych</title>
	<atom:link href="http://code42.pl/kategoria/bazy-danych/feed/" rel="self" type="application/rss+xml" />
	<link>http://code42.pl</link>
	<description>Wielkie Pytanie o Życie, Kod i całą resztę</description>
	<lastBuildDate>Wed, 25 Jan 2012 14:16:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PostgreSQL: Reset wszystkich sekwencji</title>
		<link>http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/</link>
		<comments>http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/#comments</comments>
		<pubDate>Sat, 26 Nov 2011 08:43:15 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=1287</guid>
		<description><![CDATA[Problem Czasami udaje się nam doprowadzić swoją niemałą bazę danych do takiego stanu, w którym część sekwencji będzie źle ustawiona, a tym samym nie będzie możliwe dodawanie nowych danych w standardowy sposób, gdyż kolejnym id wg sekwencji, będzie takie, które już w bazie istnieje. Możemy wtedy ręcznie naprawić daną sekwencję, zgodnie z manualem: ALTER SEQUENCE [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/counter.jpg" alt="" title="counter" width="536" height="167" class="aligncenter size-full wp-image-1291" /></p>
<h2>Problem</h2>
<p>Czasami udaje się nam doprowadzić swoją niemałą bazę danych do takiego stanu, w którym część sekwencji będzie źle ustawiona, a tym samym nie będzie możliwe dodawanie nowych danych w standardowy sposób, gdyż kolejnym id wg sekwencji, będzie takie, które już w bazie istnieje.</p>
<p>Możemy wtedy ręcznie naprawić daną sekwencję, zgodnie z manualem:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">SEQUENCE</span> serial RESTART <span style="color: #993333; font-weight: bold;">WITH</span> <span style="color: #cc66cc;">105</span>;</pre></div></div>

<p>Gdzie <code>serial</code> to nazwa sekwencji. Co jednak, gdy mamy kilkaset popsutych tabelek?</p>
<h2>Rozwiązanie — teoria</h2>
<p>Na szczęście PostgreSQL udostępnia nam duuużo informacji o każdej swojej bazie danych w schemie <code><a href="http://www.postgresql.org/docs/9.1/static/information-schema.html">information_schema</a></code>, która to zawiera zestaw zawsze dostępnych widoków. My tutaj wykorzystamy dwa:</p>
<ul>
<li><code>columns</code> — informacje o wszystkich kolumnach i widokach w bazie</li>
<li><code>constraint_column_usage</code> — informacje o kolumnach, które są obłożone jakimś <code>constraintem</code></li>
</ul>
<p>To co chcemy zrobić to:</p>
<ol>
<li>Znaleźć wszystkie zestawy tabela-kolumna-sekwencja (bazując na tym, że definicja sekwencji jest stała, zawiera wywołanie <code>nextval()</code>.</li>
<li>Dla każdej kolumny znaleźć największą wartość identyfikatora.</li>
<li>Zrestartować każdą sekwencję z wartością znalezioną w poprzednim kroku i zwiększoną o 1.</li>
</ol>
<h2>Rozwiązanie — praktyka</h2>
<p>W praktyce wystarczy wykonać poniższy kod w swojej bazie danych. Tworzy on funkcję naprawiającą sekwencje, wykonuje ją raz i a następnie ją kasuje. Należy pamiętać, że działanie jest ograniczone do schemy <em>public</em>. Jeśli chcemy naprawić inną, trzeba sobie kod lekko zmodyfikować (np. dodając nazwę schemy jako paramert).</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> rebuild_sequences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">RETURNS</span> <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">AS</span>
$body$
<span style="color: #993333; font-weight: bold;">DECLARE</span>
	sequencedefs RECORD;
	c <span style="color: #993333; font-weight: bold;">INTEGER</span>;
<span style="color: #993333; font-weight: bold;">BEGIN</span>
	<span style="color: #808080; font-style: italic;">-- Find sequence name and primary key column for every table</span>
	<span style="color: #993333; font-weight: bold;">FOR</span> sequencedefs <span style="color: #993333; font-weight: bold;">IN</span>
	<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span>
		constraint_column_usage<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">TABLE_NAME</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">TABLE_NAME</span><span style="color: #66cc66;">,</span>
		constraint_column_usage<span style="color: #66cc66;">.</span>column_name <span style="color: #993333; font-weight: bold;">AS</span> column_name<span style="color: #66cc66;">,</span>
		<span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">REPLACE</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span>column_default<span style="color: #66cc66;">,</span><span style="color: #ff0000;">''</span><span style="color: #ff0000;">'::regclass)'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">''</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'nextval('</span><span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">''</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> sequence_name
		<span style="color: #993333; font-weight: bold;">FROM</span>
			information_schema<span style="color: #66cc66;">.</span>constraint_column_usage<span style="color: #66cc66;">,</span> information_schema<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">COLUMNS</span>
		<span style="color: #993333; font-weight: bold;">WHERE</span>
			constraint_column_usage<span style="color: #66cc66;">.</span>table_schema <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'public'</span> <span style="color: #993333; font-weight: bold;">AND</span> 
			<span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span>table_schema <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'public'</span> <span style="color: #993333; font-weight: bold;">AND</span>
			<span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">TABLE_NAME</span> <span style="color: #66cc66;">=</span> constraint_column_usage<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">TABLE_NAME</span> <span style="color: #993333; font-weight: bold;">AND</span>
			constraint_column_usage<span style="color: #66cc66;">.</span>column_name <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span>column_name <span style="color: #993333; font-weight: bold;">AND</span>
			<span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span>column_default <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AND</span>
			<span style="color: #993333; font-weight: bold;">COLUMNS</span><span style="color: #66cc66;">.</span>column_default <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'nextval%'</span><span style="color: #66cc66;">&#41;</span>
	LOOP
		<span style="color: #808080; font-style: italic;">-- Find current max PK value</span>
		<span style="color: #993333; font-weight: bold;">EXECUTE</span> <span style="color: #ff0000;">'SELECT max('</span><span style="color: #66cc66;">||</span>sequencedefs<span style="color: #66cc66;">.</span>column_name<span style="color: #66cc66;">||</span><span style="color: #ff0000;">') FROM '</span> <span style="color: #66cc66;">||</span> sequencedefs<span style="color: #66cc66;">.</span><span style="color: #993333; font-weight: bold;">TABLE_NAME</span> <span style="color: #993333; font-weight: bold;">INTO</span> c;
&nbsp;
		<span style="color: #993333; font-weight: bold;">IF</span> c <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">THEN</span>
			c <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
		<span style="color: #993333; font-weight: bold;">ELSE</span>
			c <span style="color: #66cc66;">=</span> c <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>;
		<span style="color: #993333; font-weight: bold;">END</span> <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
		<span style="color: #808080; font-style: italic;">-- Rebuild sequence</span>
		<span style="color: #993333; font-weight: bold;">EXECUTE</span> <span style="color: #ff0000;">'ALTER SEQUENCE '</span> <span style="color: #66cc66;">||</span> sequencedefs<span style="color: #66cc66;">.</span>sequence_name <span style="color: #66cc66;">||</span><span style="color: #ff0000;">' RESTART WITH '</span> <span style="color: #66cc66;">||</span> c;
	<span style="color: #993333; font-weight: bold;">END</span> LOOP;
&nbsp;
	<span style="color: #993333; font-weight: bold;">RETURN</span> <span style="color: #cc66cc;">1</span>;
<span style="color: #993333; font-weight: bold;">END</span>;
$body$ <span style="color: #993333; font-weight: bold;">LANGUAGE</span> plpgsql;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span> rebuild_sequences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> rebuild_sequences<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p class="notice">Pierwsza wersja funkcji została napisana przez <a href="http://stackoverflow.com/questions/244243/how-to-reset-postgres-primary-key-sequence-when-it-falls-out-of-sync">Klausa ze StackOverflow</a>. Wersja powyżej zawiera poprawki błędów, niedociągnięć oraz formatowania.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logowanie do pliku wszystkich zapytań w PostgreSQL</title>
		<link>http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/</link>
		<comments>http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 11:20:03 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=418</guid>
		<description><![CDATA[Aby zapisywać w logach wszystkie zapytania jakie się wykonują w naszej bazie danych wystarczy zmienić tylko kilka opcji konfiguracyjnych i zrestartować serwer Postgresa. Tak więc w pliku postgresql.conf (znajdującym się katalogu, w którym trzymane są bazy, zwykle tam gdzie wskzuje zmienna PGDATA, a w „debianopodobnych” w /etc/postgresql/8.x/main/) w sekcji Error Reporting and Logging ustawiamy: log_destination = 'stderr' [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/' rel='bookmark' title='Zapamiętywanie hasła dla PostgreSQL w pliku'>Zapamiętywanie hasła dla PostgreSQL w pliku</a></li>
<li><a href='http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/' rel='bookmark' title='PostgreSQL: Reset wszystkich sekwencji'>PostgreSQL: Reset wszystkich sekwencji</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/paper-stack-536x77.jpg" alt="" title="paper-stack" width="536" height="77" class="aligncenter size-medium wp-image-717" /></p>
<p>Aby zapisywać w logach wszystkie zapytania jakie się wykonują w naszej bazie danych wystarczy zmienić tylko kilka opcji konfiguracyjnych i zrestartować serwer Postgresa.  Tak więc w pliku <code>postgresql.conf</code> (znajdującym się katalogu, w którym trzymane są bazy, zwykle tam gdzie wskzuje zmienna PGDATA, a w „debianopodobnych” w <code>/etc/postgresql/8.x/main/</code>) w sekcji Error Reporting and Logging ustawiamy:</p>
<pre class="ini">
log_destination = 'stderr'
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'all'
</pre>
<p>Gdzie:</p>
<ul>
<li><code>log_destination</code> — tak jest ustawiony domyślnie, więc tylko sprawdzamy czy się nic nie zmieniło.</li>
<li><code>logging_collector</code> — włączamy, aby logi trafiające do <code>stderr</code> mogły być zapisane do pliku.</li>
<li><code>log_directory</code> — dowolna nazwa katalogu dla logów, znajdującego się katalogu gdzie trzymamy bazę. Jeśli nie ma takiego należy go utworzyć i upewnić się, że postgres ma uprawnienia do zapisu.</li>
<li><code>log_filename</code> — nazwa pliku z logami, tutaj ze zdefiniowanym dniem.</li>
<li><code>log_statement</code> — grupa zapytań jakie chcemy zapisywać do pliku. Tutaj wybrane wszystkie. Inne opcje: none (wyłączenie zapisu), ddl (zapytania CREATE, ALTER, DROP), mod (tutaj zapewne chodzi o zapytania UPDATE, ale tego nie testowaliśmy).</li>
</ul>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/' rel='bookmark' title='Zapamiętywanie hasła dla PostgreSQL w pliku'>Zapamiętywanie hasła dla PostgreSQL w pliku</a></li>
<li><a href='http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/' rel='bookmark' title='PostgreSQL: Reset wszystkich sekwencji'>PostgreSQL: Reset wszystkich sekwencji</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zapamiętywanie hasła dla PostgreSQL w pliku</title>
		<link>http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/</link>
		<comments>http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 11:38:35 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=404</guid>
		<description><![CDATA[Jeśli często korzystamy z psql, gdzie wymagana jest autoryzacja, lub też chcemy umożliwić wykonanie jakiegoś skryptu automatycznie (np. z crona) można zapamiętać sobie hasło w specjalnym pliku ~/.pgpass. Składnia jest następująca: host:port:baza:użytkownik:hasło host2:port2:baza2:użytkownik2:hasło2 … Przy czym można użyć *, jeśli nie chcemy jednoznacznie identyfikować któregoś parametru (oprócz hasła oczywiście). Należy pamiętać, że podczas łączenia może być koniecznie podanie [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/sad-girl-forgot-her-password-536x178.jpg" alt="" title="sad-girl-forgot-her-password" width="536" height="178" class="aligncenter size-medium wp-image-714" /></p>
<p>Jeśli często korzystamy z <code>psql</code>, gdzie wymagana jest autoryzacja, lub też chcemy umożliwić wykonanie jakiegoś skryptu automatycznie (np. z crona) można zapamiętać sobie hasło w specjalnym pliku<code> ~/.pgpass</code>. Składnia jest następująca:</p>
<pre>
host:port:baza:użytkownik:hasło
host2:port2:baza2:użytkownik2:hasło2
…
</pre>
<p>Przy czym można użyć *, jeśli nie chcemy jednoznacznie identyfikować któregoś parametru (oprócz hasła oczywiście). Należy pamiętać, że podczas łączenia może być koniecznie podanie hosta i użytkownika, ponieważ ten mechanizm służy jedynie do dopasowywania samych haseł. Na koniec bardziej życiowy przykład dla tych, co tylko kod czytają:</p>
<pre>
*:*:produkty:admin:tajnehaslo
</pre>
<p class="notice">AKTUALIZACJA: Tak jak Mistrz Wu w komentarzu sugeruje, nie tyle warto co trzeba zmienić uprawnienia dla tego pliku na 0600. Po dodaniu uprawnień dla grup i innych plik byłby ignorowany.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
<li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PostgreSQL: obliczanie odstępów czasu</title>
		<link>http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/</link>
		<comments>http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 15:10:29 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=165</guid>
		<description><![CDATA[Jak sprawdzić ile godzin minęło od utworzenia rekordu (lub po prostu obliczyć odstęp czasu od dowolnego momentu)? Trzeba skorzystać z funkcji epoch i extract: SELECT EXTRACT &#40;epoch FROM &#40;now&#40;&#41; - created_at&#41;&#41;/3600 AS lifetime FROM … Zakładając oczywiście, że w kolumnie created_at trzymamy dokładny czas utworzenia rekordu. Funkcja extract może operować na timestampach (znacznikach czasu) i interwałach (wynik [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/' rel='bookmark' title='Zapamiętywanie hasła dla PostgreSQL w pliku'>Zapamiętywanie hasła dla PostgreSQL w pliku</a></li>
<li><a href='http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/' rel='bookmark' title='PostgreSQL: Reset wszystkich sekwencji'>PostgreSQL: Reset wszystkich sekwencji</a></li>
<li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/clock-time-536x197.jpg" alt="" title="clock-time" width="536" height="197" class="aligncenter size-medium wp-image-688" /></p>
<p>Jak sprawdzić ile godzin minęło od utworzenia rekordu (lub po prostu obliczyć odstęp czasu od dowolnego momentu)? Trzeba skorzystać z funkcji <code>epoch</code> i <code>extract</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">EXTRACT</span> <span style="color: #66cc66;">&#40;</span>epoch <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span>now<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> created_at<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">3600</span> <span style="color: #993333; font-weight: bold;">AS</span> lifetime <span style="color: #993333; font-weight: bold;">FROM</span> …</pre></div></div>

<p>Zakładając oczywiście, że w kolumnie <code>created_at</code> trzymamy dokładny czas utworzenia rekordu. Funkcja <code>extract</code> może operować na <code>timestampach</code> (znacznikach czasu) i interwałach (wynik działania <code>now() - created_at</code> jest właśnie interwałem). Powyższe zapytanie oblicza godziny, ponieważ <code>extract</code> zwraca sekundy, które później dzielimy przez 3600.</p>
<p>Poza zaprezentowanym przykładem, możemy „extractować” wiele innych wartości, takich jak:</p>
<ul>
<li><code>century</code></li>
<li><code>day</code></li>
<li><code>decade</code></li>
<li><code>dow</code> (dzień tygodnia)</li>
<li><code>epoch</code></li>
<li><code>hour</code></li>
<li><code>isodow</code></li>
<li><code>isoyear</code></li>
<li><code>microseconds</code></li>
<li><code>millennium</code></li>
<li><code>milliseconds</code></li>
<li><code>minute</code></li>
<li><code>month</code></li>
<li><code>quarter</code></li>
<li><code>second</code></li>
<li><code>timezone</code></li>
<li><code>timezone_hour</code></li>
<li><code>timezone_minute</code></li>
<li><code>week</code></li>
<li><code>year</code></li>
</ul>
<p>Szczegóły w <a href='http://www.postgresql.org/docs/8.3/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT'>dokumentacji</a>.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2009/06/30/zapamietywanie-hasla-dla-postgresql-w-pliku/' rel='bookmark' title='Zapamiętywanie hasła dla PostgreSQL w pliku'>Zapamiętywanie hasła dla PostgreSQL w pliku</a></li>
<li><a href='http://code42.pl/2011/11/26/postgresql-reset-wszystkich-sekwencji/' rel='bookmark' title='PostgreSQL: Reset wszystkich sekwencji'>PostgreSQL: Reset wszystkich sekwencji</a></li>
<li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aktualizacja oprogramowania a wydajność</title>
		<link>http://code42.pl/2008/12/19/aktualizacja-oprogramowania-a-wydajnosc/</link>
		<comments>http://code42.pl/2008/12/19/aktualizacja-oprogramowania-a-wydajnosc/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 11:54:35 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[apache benchmark]]></category>
		<category><![CDATA[optymalizacja]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=79</guid>
		<description><![CDATA[Krótkie spostrzeżenie na temat wydajności aplikacji (praktycznie nie wypełnionej danymi) po następujących aktualizacjach: Symfony 1.1 → Symfony 1.2 Propel 1.2 → Propel 1.3 PHP 5.2.0 → PHP 5.2.6 PostgreSQL 8.1 → PostgreSQL 8.3 Prosty test został wykonany za pomocą ApacheBenchmarka: ab -c 5 -n 300 -H 'Connection: close'. Jak widać symulacja bazowała na 300 użytkownikach, przy czym [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
<li><a href='http://code42.pl/2009/03/31/walidacja-jednego-pola-formularza-w-symfony/' rel='bookmark' title='Walidacja jednego pola formularza w symfony'>Walidacja jednego pola formularza w symfony</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/speedometer-536x282.jpg" alt="" title="speedometer" width="536" height="282" class="aligncenter size-medium wp-image-676" /></p>
<p>Krótkie spostrzeżenie na temat wydajności aplikacji (praktycznie nie wypełnionej danymi) po następujących aktualizacjach:</p>
<ul>
<li>Symfony 1.1 → Symfony 1.2</li>
<li>Propel 1.2 → Propel 1.3</li>
<li>PHP 5.2.0 → PHP 5.2.6</li>
<li>PostgreSQL 8.1 → PostgreSQL 8.3</li>
</ul>
<p>Prosty test został wykonany za pomocą <a href='http://code42.pl/?p=93' title='Connection: close + Apache Benchmark'>ApacheBenchmarka</a>:<br />
<code>ab -c 5 -n 300 -H 'Connection: close'</code>. Jak widać symulacja bazowała na 300 użytkownikach, przy czym do 5 na raz wchodziło na stronę.</p>
<h2>Przed aktualizacją</h2>
<p>Próba 1:</p>
<pre>
Requests per second:    4.34 [#/sec] (mean)
Time per request:       1152.770 [ms] (mean)
Time per request:       230.554 [ms] (mean, across all concurrent requests)
</pre>
<p>Próba 2:</p>
<pre>
Requests per second:    4.79 [#/sec] (mean)
Time per request:       1043.581 [ms] (mean)
Time per request:       208.716 [ms] (mean, across all concurrent requests)
</pre>
<h2>Po aktualizacji</h2>
<p>Próba 1:</p>
<pre>
Requests per second:    5.33 [#/sec] (mean)
Time per request:       937.318 [ms] (mean)
Time per request:       187.464 [ms] (mean, across all concurrent requests)
</pre>
<p>Próba 2:</p>
<pre>
Requests per second:    5.39 [#/sec] (mean)
Time per request:       927.979 [ms] (mean)
Time per request:       185.596 [ms] (mean, across all concurrent requests)
</pre>
<p>Oczywiście z uwagi na brak testów pomiędzy poszczególnymi zmianami ciężko jest powiedzieć coś więcej, niż tyle że warto aktualizować, choćby o tego jednego requesta na sekundę ;). Ot, taka ciekawostka.</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/' rel='bookmark' title='Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1'>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</a></li>
<li><a href='http://code42.pl/2009/01/14/czas-zycia-krotki-w-postgresie/' rel='bookmark' title='PostgreSQL: obliczanie odstępów czasu'>PostgreSQL: obliczanie odstępów czasu</a></li>
<li><a href='http://code42.pl/2009/03/31/walidacja-jednego-pola-formularza-w-symfony/' rel='bookmark' title='Walidacja jednego pola formularza w symfony'>Walidacja jednego pola formularza w symfony</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2008/12/19/aktualizacja-oprogramowania-a-wydajnosc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Migracja MySQL → PostgreSQL aplikacji w Symfony 1.1</title>
		<link>http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/</link>
		<comments>http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 10:05:23 +0000</pubDate>
		<dc:creator>zergu</dc:creator>
				<category><![CDATA[Bazy danych]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[propel]]></category>

		<guid isPermaLink="false">http://code42.pl/?p=5</guid>
		<description><![CDATA[Jako, że w MySQL nie dzieje się najlepiej postanowiliśmy zmigrować jeden z naszych projektów na Postgresa. Bazuje on na Symfony 1.1, co oznacza starego Propela 1.2. Samo przestawienie połączenia nie stwarzało większych problemów, wystarczyło w databases.yml i propel.ini przerobić mysql na pgsql: all: propel: class: sfPropelDatabase param: persistent: true phptype: pgsql … propel.database = pgsql propel.database.createUrl = pgsql://zdzislaw@localhost/ [...]


Podobne wpisy:<ol><li><a href='http://code42.pl/2008/12/19/aktualizacja-oprogramowania-a-wydajnosc/' rel='bookmark' title='Aktualizacja oprogramowania a wydajność'>Aktualizacja oprogramowania a wydajność</a></li>
<li><a href='http://code42.pl/2009/01/05/symfony-paginacja-przy-wlasnychnietypowych-warunkach-sql/' rel='bookmark' title='Symfony: Paginacja przy własnych/nietypowych warunkach SQL'>Symfony: Paginacja przy własnych/nietypowych warunkach SQL</a></li>
<li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://code42.pl/wp-content/uploads/great-migration-536x194.jpg" alt="" title="great-migration" width="536" height="194" class="aligncenter size-medium wp-image-672" /></p>
<p>Jako, że w <a title="Założyciel MySQL ostrzega przed aktualną wersją" href="http://www.heise-online.pl/news/Zalozyciel-MySQL-ostrzega-przed-aktualna-wersja--/6612">MySQL nie dzieje się najlepiej</a> postanowiliśmy zmigrować jeden z naszych projektów na Postgresa. Bazuje on na Symfony 1.1, co oznacza starego Propela 1.2. </p>
<p>Samo przestawienie połączenia nie stwarzało większych problemów, wystarczyło w <code>databases.yml</code> i <code>propel.ini</code> przerobić <code>mysql</code> na <code>pgsql</code>:</p>
<pre>
all:
  propel:
    class:          sfPropelDatabase
    param:
    persistent:       true
    phptype:          pgsql
…
</pre>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;">propel.database            <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> pgsql</span>
propel.database.createUrl  <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> pgsql://zdzislaw@localhost/</span>
propel.database.url        <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> pgsql://zdzislaw@localhost/piwo</span></pre></div></div>

<p>Przebudowanie modelu, utworzeniu bazy i jej struktury również wykonało się bez problemu, ale to był koniec tego dobrego.</p>
<h2>Brak SERIAL</h2>
<p>Niestety, propelowy generator skryptu SQL tworzącego schemat bazy nie uraczył nas typem <code>SERIAL</code> przy identyfikatorach, jednakże w samej aplikacji nie stwarza to problemów, ponieważ sekwencje i bez tego są wykorzystywane. Także trzeba po prostu uważać podczas zabawy w <abbr title='Command Line Interface'>CLI</abbr> Postgresa, gdy mogą one doprowadzić do anomalii z identyfikatorami.</p>
<h2>Dane binarne pobierane „ręcznie”</h2>
<p>Drobny problem pojawił się w miejscach, gdzie pobieraliśmy dane binarne (BLOB/BYTEA) własnym zapytaniem, omijając wbudowany we framework Active Record. Dane takie trzeba było dodatkowo „od-eskejpować” funkcją <a href='http://php.net/manual/en/function.stripcslashes.php'><code>stripcslashes</code></a>.</p>
<p class='notice'>
AKTUALIZACJA: Po aktualizacji projektu do Symfony 1.2 (chociaż tutaj właściwie chodzi o aktualizację Propela do wersji 1.3) okazało się, że żadne <code>stripcslashes</code> nie będzie potrzebne, ponieważ dane binarne (blob) są pobierane jako… stream. Innymi słowy, przy zapytaniach tworzonych samodzielnie, do akcji musiała wkroczyć funkcja <a href='http://php.net/manual/en/function.stream-get-contents.php'><code>stream_get_contents</code></a>.
</p>
<h2>GROUP BY</h2>
<p>Najwięcej problemów sprawiło grupowanie, ponieważ PostgreSQL ostro trzyma się standardów i wymusza podanie wszystkich używanych kolumn w klauzuli <code>GROUP BY</code>. MySQL natomiast „po cichu” sam sobie je dołączał. Różnicę w zachowaniu prezentuje poniższy (nie mający większego sensu) przykład:</p>
<pre>psql=# select sum(id), id from users;
ERROR:  column "users.id" must appear in the GROUP BY clause
or be used in an aggregate function</pre>
<pre>mysql>  select sum(id), id from users;
+---------+----+
| sum(id) | id |
+---------+----+
|  45     |  1 |
+---------+----+
</pre>
<h2>CONCAT</h2>
<p>Łącznie ciągów znaków odbywa się całkiem inaczej w MySQL i PgSQL. W tym pierwszym wykonuje się to za pomocą funkcji <code>CONCAT()</code>, natomiast w drugim wykorzystuje się operator <code>||</code>. Także trzeba było wykonać małą robótkę ręczną.</p>
<h2>FORMAT</h2>
<p>W naszym kodzie używaliśmy MySQL-owego <code>FORMAT()</code>, aby ograniczyć liczbę cyfr po przecinku, którego w Postgresie nie ma. Można by tutaj użyć funkcji <code>ROUND()</code>, obecnej i tu i tu, jednak zdecydowaliśmy się przenieść rozwiązanie tego problemu do warstwy języka programowania.</p>
<h2>LIKE</h2>
<p><code>LIKE</code> w Postgresie, w przeciwieństwie do MySQL, rozróżnia wielkość znaków. Jednak naprawa tej przypadłości sprowadza się jedynie od zamiany <code>LIKE</code> na <code>ILIKE</code>.</p>
<h2>Coś dziwnego</h2>
<p>Na koniec coś, czego do końca nie udało nam się zrozumieć. Zaraz po przestawieniu konfiguracji na <code>pgsql</code>, strona przestała odpowiadać (a dokładniej odpowiadała, gdy połączenie z bazą przekroczyło czas oczekiwania). Niemniej jednak PostgreSQL sam w sobie działał, jak również możliwe było połączenie z „czystego” PHP. Jedynie aplikacja Symfony dziwnie się zachowywała. W logach pojawiało się następujące stwierdzenie:</p>
<p><code>Dec  4 11:20:22 myhost httpd:  [wrapped: Could not connect [Native Error: pg_pconnect() [function.pg-pconnect]: Unable to connect to PostgreSQL server: server closed the connection unexpectedly  This probably means the server terminated abnormally    before or while processing the request.] [User Info: host=localhost port=80 dbname='piwo' user='zdzislaw'] [User Info: Array]]</code></p>
<p>Taka sama sytuacja powtórzyła się na dwóch różnych maszynach (jednak na tym samym <a title="Arch Linux" href="http://archlinux.org">systemie operacyjnym</a>). Niezrozumiałe jest to, że w czasie różnych zabaw z konfiguracją wszystko wracało do normy, jednak nie bardzo da się znaleźć konkretną przyczynę. Innymi słowy nie potrafimy zreprodukować tej sytuacji.</p>
<h2>Krótkie podsumowanie</h2>
<p>Migracja rozwiniętego projektu w Symfony okazała się być stosunkowo mało problematyczna. Kłopotów mogło by być jeszcze mniej, gdyby unikać rozwiązań specyficznych dla danego systemu baz danych. Ale w końcu jak często migruje się z jednej systemu zarządzania bazami danych do innego?</p>


<p>Podobne wpisy:<ol><li><a href='http://code42.pl/2008/12/19/aktualizacja-oprogramowania-a-wydajnosc/' rel='bookmark' title='Aktualizacja oprogramowania a wydajność'>Aktualizacja oprogramowania a wydajność</a></li>
<li><a href='http://code42.pl/2009/01/05/symfony-paginacja-przy-wlasnychnietypowych-warunkach-sql/' rel='bookmark' title='Symfony: Paginacja przy własnych/nietypowych warunkach SQL'>Symfony: Paginacja przy własnych/nietypowych warunkach SQL</a></li>
<li><a href='http://code42.pl/2009/07/21/logowanie-do-pliku-wszystkich-zapytan-w-postgresql/' rel='bookmark' title='Logowanie do pliku wszystkich zapytań w PostgreSQL'>Logowanie do pliku wszystkich zapytań w PostgreSQL</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://code42.pl/2008/12/15/migracja-mysql%c2%a0%e2%86%92-postgresql-aplikacji-w-symfony-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

